diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..e69de29b
diff --git a/docs/docs/assets/images/others/monitor/query/img.png b/docs/docs/assets/images/others/monitor/query/img.png
new file mode 100644
index 00000000..37cf9d99
Binary files /dev/null and b/docs/docs/assets/images/others/monitor/query/img.png differ
diff --git a/docs/docs/assets/images/others/monitor/query/img_1.png b/docs/docs/assets/images/others/monitor/query/img_1.png
new file mode 100644
index 00000000..8c11d08d
Binary files /dev/null and b/docs/docs/assets/images/others/monitor/query/img_1.png differ
diff --git a/docs/docs/assets/images/others/monitor/query/img_2.png b/docs/docs/assets/images/others/monitor/query/img_2.png
new file mode 100644
index 00000000..d4294109
Binary files /dev/null and b/docs/docs/assets/images/others/monitor/query/img_2.png differ
diff --git a/docs/docs/assets/images/others/monitor/query/img_3.png b/docs/docs/assets/images/others/monitor/query/img_3.png
new file mode 100644
index 00000000..28585dd7
Binary files /dev/null and b/docs/docs/assets/images/others/monitor/query/img_3.png differ
diff --git a/docs/docs/assets/images/query/img.png b/docs/docs/assets/images/query/img.png
new file mode 100644
index 00000000..07bc9fad
Binary files /dev/null and b/docs/docs/assets/images/query/img.png differ
diff --git a/docs/docs/assets/images/query/snippet/img.png b/docs/docs/assets/images/query/snippet/img.png
new file mode 100644
index 00000000..3043b11b
Binary files /dev/null and b/docs/docs/assets/images/query/snippet/img.png differ
diff --git a/docs/docs/assets/images/query/snippet/img_1.png b/docs/docs/assets/images/query/snippet/img_1.png
new file mode 100644
index 00000000..52130586
Binary files /dev/null and b/docs/docs/assets/images/query/snippet/img_1.png differ
diff --git a/docs/docs/assets/images/query/snippet/img_2.png b/docs/docs/assets/images/query/snippet/img_2.png
new file mode 100644
index 00000000..acc660f4
Binary files /dev/null and b/docs/docs/assets/images/query/snippet/img_2.png differ
diff --git a/docs/docs/assets/images/query/snippet/img_3.png b/docs/docs/assets/images/query/snippet/img_3.png
new file mode 100644
index 00000000..253585ff
Binary files /dev/null and b/docs/docs/assets/images/query/snippet/img_3.png differ
diff --git a/docs/docs/assets/images/query/snippet/img_4.png b/docs/docs/assets/images/query/snippet/img_4.png
new file mode 100644
index 00000000..6f330b0c
Binary files /dev/null and b/docs/docs/assets/images/query/snippet/img_4.png differ
diff --git a/docs/docs/assets/images/versions/1.15.0/img.png b/docs/docs/assets/images/versions/1.15.0/img.png
new file mode 100644
index 00000000..2433e627
Binary files /dev/null and b/docs/docs/assets/images/versions/1.15.0/img.png differ
diff --git a/docs/docs/assets/images/versions/1.15.0/img_1.png b/docs/docs/assets/images/versions/1.15.0/img_1.png
new file mode 100644
index 00000000..bcc87eea
Binary files /dev/null and b/docs/docs/assets/images/versions/1.15.0/img_1.png differ
diff --git a/docs/docs/assets/images/versions/1.15.0/img_2.png b/docs/docs/assets/images/versions/1.15.0/img_2.png
new file mode 100644
index 00000000..ff93e984
Binary files /dev/null and b/docs/docs/assets/images/versions/1.15.0/img_2.png differ
diff --git a/docs/docs/assets/images/versions/1.15.0/img_3.png b/docs/docs/assets/images/versions/1.15.0/img_3.png
new file mode 100644
index 00000000..b9073bc1
Binary files /dev/null and b/docs/docs/assets/images/versions/1.15.0/img_3.png differ
diff --git a/docs/docs/assets/images/versions/1.15.0/img_4.png b/docs/docs/assets/images/versions/1.15.0/img_4.png
new file mode 100644
index 00000000..2e2fc7a3
Binary files /dev/null and b/docs/docs/assets/images/versions/1.15.0/img_4.png differ
diff --git a/docs/docs/assets/images/versions/1.15.0/img_5.png b/docs/docs/assets/images/versions/1.15.0/img_5.png
new file mode 100644
index 00000000..e9288db3
Binary files /dev/null and b/docs/docs/assets/images/versions/1.15.0/img_5.png differ
diff --git a/docs/docs/assets/images/versions/1.15.0/img_6.png b/docs/docs/assets/images/versions/1.15.0/img_6.png
new file mode 100644
index 00000000..4089f073
Binary files /dev/null and b/docs/docs/assets/images/versions/1.15.0/img_6.png differ
diff --git a/docs/docs/assets/images/versions/1.15.0/img_7.png b/docs/docs/assets/images/versions/1.15.0/img_7.png
new file mode 100644
index 00000000..3a3472e1
Binary files /dev/null and b/docs/docs/assets/images/versions/1.15.0/img_7.png differ
diff --git a/docs/docs/assets/images/versions/1.15.0/img_8.png b/docs/docs/assets/images/versions/1.15.0/img_8.png
new file mode 100644
index 00000000..41e9e086
Binary files /dev/null and b/docs/docs/assets/images/versions/1.15.0/img_8.png differ
diff --git a/docs/docs/assets/images/versions/1.15.0/img_9.png b/docs/docs/assets/images/versions/1.15.0/img_9.png
new file mode 100644
index 00000000..17c77de7
Binary files /dev/null and b/docs/docs/assets/images/versions/1.15.0/img_9.png differ
diff --git a/docs/docs/assets/images/versions/1.15.0/themes.png b/docs/docs/assets/images/versions/1.15.0/themes.png
new file mode 100644
index 00000000..d1630c73
Binary files /dev/null and b/docs/docs/assets/images/versions/1.15.0/themes.png differ
diff --git a/docs/docs/development/version/1.15.0-development.md b/docs/docs/development/version/1.16.0-development.md
similarity index 91%
rename from docs/docs/development/version/1.15.0-development.md
rename to docs/docs/development/version/1.16.0-development.md
index 4ab27505..21f917ab 100644
--- a/docs/docs/development/version/1.15.0-development.md
+++ b/docs/docs/development/version/1.16.0-development.md
@@ -3,7 +3,7 @@ template: overrides/main.html
icon: material/gesture-tap-button
---
-DBM Version for `1.15.0` is development!
+DBM Version for `1.16.0` is development!
!!! danger "Warning"
diff --git a/docs/docs/reference/monitor/monitor_query.md b/docs/docs/reference/monitor/monitor_query.md
new file mode 100644
index 00000000..ea9020fa
--- /dev/null
+++ b/docs/docs/reference/monitor/monitor_query.md
@@ -0,0 +1,54 @@
+---
+template: overrides/main.html
+---
+
+This document mainly introduces how we can use the `Slow query` monitoring function provided by the software.
+
+Move the mouse to the top menu `Monitor` and wait for the drop-down options to appear, click `Query` to enter the query monitoring interface, which is similar to the following page
+
+
+
+The upper part of the page is the data chart display & function configuration area, and the lower part is the detailed data list area
+
+#### Data charting & Feature Configuration
+
+---
+
+The drop-down selection box on the top left is used to select the configured data source. After selection, the software will initiate a request to the service to obtain information, and return a data chart similar to the following
+
+
+
+There is a `Number` input device at the top right
+
+`Numeric input` is used to mark the maximum time-consuming limit of the query (unit: milliseconds)
+
+#### Details of the data
+
+---
+
+The drop-down selection box on the top left is used to select the configured data source. After selection, the software will initiate a request to the service to obtain information, and return results similar to the following
+
+
+
+| Property | Description |
+|--------------|------------------------------------------------------------|
+| user | Query the user used |
+| host | Query the client host |
+| hash | Query the generated hash data |
+| time | Query creation time |
+| elapsed(ms) | Query time (ms) |
+| memoryUsage | Memory used by query |
+| rows | Query the total number of rows |
+| bytes | Total number of bytes queried |
+| readRows | Query the total number of rows of read metadata |
+| bytesRead | Query the total number of bytes of metadata read |
+| writtenRows | The total number of bytes of metadata written to the query |
+| bytesWritten | The total number of bytes of metadata written to the query |
+
+#### Action
+
+---
+
+:octicons-search-16:{.blue} button To query the DDL statement of the operation
+
+
diff --git a/docs/docs/reference/query/query_history.md b/docs/docs/reference/query/query_history.md
index 1c207a58..8002da2a 100644
--- a/docs/docs/reference/query/query_history.md
+++ b/docs/docs/reference/query/query_history.md
@@ -4,10 +4,6 @@ template: overrides/main.html
The query history function is mainly used to mark some of our query records for each data source.
-!!! warning
-
- Currently supports up to `100` query history, we will expand this function to support more data storage in the future!
-
Move the mouse to the top menu `Query` and wait for the drop-down options to appear, click `History` to enter the query history interface, which is similar to the following page

@@ -31,10 +27,24 @@ On the top right side of the page we can see the ",
"description": "ClickHouse DataBase GUI",
"github": "https://github.com/EdurtIO/dbm.git",
@@ -59,11 +59,12 @@
"highcharts": "^9.3.2",
"jsstore": "^4.3.8",
"lodash": "^4.17.21",
- "moment": "^2.29.1",
+ "moment": "^2.29.2",
"ng-zorro-antd": "^12.1.0",
"ngx-clipboard": "^14.0.2",
"ngx-easy-table": "^15.2.0",
"ngx-markdown": "^13.1.0",
+ "ngx-moment": "^6.0.2",
"node-sql-parser": "^4.1.1",
"rxjs": "~6.6.0",
"sass-loader": "^12.3.0",
diff --git a/src/renderer/app/app.module.ts b/src/renderer/app/app.module.ts
index 7b925b86..bd055199 100644
--- a/src/renderer/app/app.module.ts
+++ b/src/renderer/app/app.module.ts
@@ -5,7 +5,7 @@ import { AppComponent } from './app.component';
import { CommonModule, HashLocationStrategy, LocationStrategy } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { NzConfig, NZ_CONFIG } from 'ng-zorro-antd/core/config';
+import { NZ_CONFIG, NzConfig } from 'ng-zorro-antd/core/config';
const ngZorroConfig: NzConfig = {
card: {
@@ -13,6 +13,12 @@ const ngZorroConfig: NzConfig = {
},
button: {
nzSize: 'small'
+ },
+ table: {
+ nzSize: 'small'
+ },
+ modal: {
+ nzMaskClosable: false
}
};
@@ -32,8 +38,8 @@ const ngZorroConfig: NzConfig = {
provide: LocationStrategy,
useClass: HashLocationStrategy
},
- { provide: NZ_CONFIG, useValue: ngZorroConfig }
-],
+ {provide: NZ_CONFIG, useValue: ngZorroConfig}
+ ],
bootstrap: [AppComponent]
})
export class AppModule {
diff --git a/src/renderer/app/common-share.module.ts b/src/renderer/app/common-share.module.ts
index d9d63005..19e0b6f8 100644
--- a/src/renderer/app/common-share.module.ts
+++ b/src/renderer/app/common-share.module.ts
@@ -3,7 +3,7 @@ import { DdlQueryComponent } from '@renderer/components/query/ddl/ddl.query.comp
import { NgZorroAntdModule } from '@renderer/app/ng-zorro-antd.module';
import { TranslateModule } from '@ngx-translate/core';
import { CodemirrorModule } from '@ctrl/ngx-codemirror';
-import { FormsModule } from '@angular/forms';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ClipboardComService } from '@renderer/services/other/clipboard.service';
import { BasicTableComponent } from '@renderer/components/table/basic/basic.table.component';
import { CommonModule } from '@angular/common';
@@ -13,6 +13,8 @@ import { ChartModule } from 'angular-highcharts';
import { EmptyAntdComponent } from '@renderer/components/antd/empty/empty.antd.component';
import { DrividerAntdComponent } from '@renderer/components/antd/drivider/drivider.antd.component';
import { TableModule } from 'ngx-easy-table';
+import { MomentModule } from 'ngx-moment';
+import { CreateSnippetComponent } from '@renderer/components/snippet/create/create.snippet.component';
@NgModule({
imports: [
@@ -23,14 +25,17 @@ import { TableModule } from 'ngx-easy-table';
CommonModule,
ServiceModule,
ChartModule,
- TableModule
+ TableModule,
+ MomentModule,
+ ReactiveFormsModule
],
declarations: [
DdlQueryComponent,
BasicTableComponent,
LineChartsComponent,
EmptyAntdComponent,
- DrividerAntdComponent
+ DrividerAntdComponent,
+ CreateSnippetComponent
],
providers: [
ClipboardComService
@@ -40,7 +45,8 @@ import { TableModule } from 'ngx-easy-table';
BasicTableComponent,
LineChartsComponent,
EmptyAntdComponent,
- DrividerAntdComponent
+ DrividerAntdComponent,
+ CreateSnippetComponent
]
})
export class CommonShareModule {
diff --git a/src/renderer/app/layout/header/header.component.html b/src/renderer/app/layout/header/header.component.html
index 837e3cab..5e3c8b65 100644
--- a/src/renderer/app/layout/header/header.component.html
+++ b/src/renderer/app/layout/header/header.component.html
@@ -18,6 +18,11 @@
{{ 'common.history' | translate }}
+
+
+ {{ 'common.snippet' | translate }}
+
+
@@ -110,9 +115,8 @@
{{version}}
-
+ (nzOnCancel)="handlerUpdate(false)" [nzMaskClosable]="false" [nzClosable]="false" nzWidth="80%">
{{'common.update'|translate}}
{{'common.cancel'|translate}}
+ [disabled]="!disabled.button">{{'common.cancel'|translate}}
-
\ No newline at end of file
+
diff --git a/src/renderer/app/layout/layout.component.html b/src/renderer/app/layout/layout.component.html
index 2fc6ae8b..31276e62 100644
--- a/src/renderer/app/layout/layout.component.html
+++ b/src/renderer/app/layout/layout.component.html
@@ -7,8 +7,29 @@
App
+ 0" nzType="error" nzBanner [nzMessage]="alertTemplate">
+
+ {{'alert.migrate_datasource'|translate}}
+
+ {{'common.migrte'|translate}}
+
+
+
-
+ Design ©2021 Implement By EdurtIO
+
+
+
+
+ {{migrateConfirmMessage}}
+
+
+ {{'common.migrte'|translate}}
+
+
+
diff --git a/src/renderer/app/layout/layout.component.ts b/src/renderer/app/layout/layout.component.ts
index 42b3b01c..2cc68545 100644
--- a/src/renderer/app/layout/layout.component.ts
+++ b/src/renderer/app/layout/layout.component.ts
@@ -3,6 +3,11 @@ import { TranslateService } from '@ngx-translate/core';
import { BasicService } from '@renderer/services/system/basic.service';
import { SystemBasicModel } from '@renderer/model/system.model';
import { TranslateUtils } from '@renderer/utils/translate.utils';
+import { StringUtils } from '@renderer/utils/string.utils';
+import { DatasourceService } from '@renderer/services/management/datasource.service';
+import { RequestUtils } from '@renderer/utils/request.utils';
+import { DatasourceModel } from '@renderer/model/datasource.model';
+import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'app-layout',
@@ -37,13 +42,48 @@ import { TranslateUtils } from '@renderer/utils/translate.utils';
]
})
export class LayoutComponent implements OnInit {
+ visible: boolean = false;
+ migrateConfirmMessage: string;
+ migrateLoading: boolean = false;
+ dataSources: DatasourceModel[] = new Array();
+
constructor(private translate: TranslateService,
- private basicService: BasicService) {
+ private basicService: BasicService,
+ private messageService: NzMessageService,
+ private dataSourceService: DatasourceService) {
const basicConfig = this.basicService.get() === null ? new SystemBasicModel() : this.basicService.get();
this.translate.setDefaultLang(basicConfig.language);
TranslateUtils.init(translate);
+ this.initDataSources();
}
ngOnInit() {
}
+
+ initDataSources() {
+ this.dataSources = JSON.parse(localStorage.getItem(RequestUtils.KEY_DATASOURCE));
+ }
+
+ handlerMigrateShow(value: boolean) {
+ this.visible = value;
+ if (value) {
+ this.migrateConfirmMessage = StringUtils.format(this.translate.instant('formatter.migrate_data'),
+ [this.dataSources.length]);
+ }
+ }
+
+ handlerMigrate() {
+ this.migrateLoading = true;
+ this.dataSources.forEach(dataSource => {
+ this.dataSourceService.save(dataSource).then(() => {
+ }).catch(error => {
+ this.messageService.error(error);
+ });
+ });
+ this.migrateLoading = false;
+ this.visible = false;
+ localStorage.removeItem(RequestUtils.KEY_DATASOURCE);
+ this.initDataSources();
+ this.messageService.success(this.translate.instant('common.success'));
+ }
}
diff --git a/src/renderer/app/layout/layout.module.ts b/src/renderer/app/layout/layout.module.ts
index 1b81543a..993d4f44 100644
--- a/src/renderer/app/layout/layout.module.ts
+++ b/src/renderer/app/layout/layout.module.ts
@@ -10,6 +10,8 @@ import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { NgZorroAntdModule } from '@renderer/app/ng-zorro-antd.module';
import { BasicService } from '@renderer/services/system/basic.service';
import { MarkdownModule } from 'ngx-markdown';
+import { DatasourceService } from '@renderer/services/management/datasource.service';
+import { HttpService } from '@renderer/services/http.service';
const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader =>
new TranslateHttpLoader(http, './renderer/assets/i18n/', '.json');
@@ -34,7 +36,9 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader =>
})
],
providers: [
- BasicService
+ BasicService,
+ DatasourceService,
+ HttpService
]
})
export class LayoutModule {
diff --git a/src/renderer/app/layout/layout.routing.ts b/src/renderer/app/layout/layout.routing.ts
index 2755c895..1432df8f 100644
--- a/src/renderer/app/layout/layout.routing.ts
+++ b/src/renderer/app/layout/layout.routing.ts
@@ -20,6 +20,10 @@ const LAYOUT_ROUTES: Routes = [
path: 'query',
loadChildren: () => import('../pages/query/query/query.module').then(m => m.QueryModule)
},
+ {
+ path: 'snippet',
+ loadChildren: () => import('../pages/query/snippet/snippet.module').then(m => m.SnippetModule)
+ },
{
path: 'history',
loadChildren: () => import('../pages/query/history/history.module').then(m => m.HistoryModule)
diff --git a/src/renderer/app/ng-zorro-antd.module.ts b/src/renderer/app/ng-zorro-antd.module.ts
index e1953371..cc962f07 100644
--- a/src/renderer/app/ng-zorro-antd.module.ts
+++ b/src/renderer/app/ng-zorro-antd.module.ts
@@ -35,6 +35,8 @@ import { NzResultModule } from 'ng-zorro-antd/result';
import { NzCollapseModule } from 'ng-zorro-antd/collapse';
import { NzBadgeModule } from 'ng-zorro-antd/badge';
import { NzPaginationModule } from 'ng-zorro-antd/pagination';
+import { NzDrawerModule } from 'ng-zorro-antd/drawer';
+import { NzTypographyModule } from 'ng-zorro-antd/typography';
@NgModule({
declarations: [],
@@ -74,7 +76,9 @@ import { NzPaginationModule } from 'ng-zorro-antd/pagination';
NzResultModule,
NzCollapseModule,
NzBadgeModule,
- NzPaginationModule
+ NzPaginationModule,
+ NzDrawerModule,
+ NzTypographyModule
]
})
export class NgZorroAntdModule {
diff --git a/src/renderer/app/pages/home/home.component.ts b/src/renderer/app/pages/home/home.component.ts
index 83647aee..9dd11624 100644
--- a/src/renderer/app/pages/home/home.component.ts
+++ b/src/renderer/app/pages/home/home.component.ts
@@ -5,6 +5,7 @@ import { DatasourceService } from '@renderer/services/management/datasource.serv
import { QueryService } from '@renderer/services/query/query.service';
import { RequestModel } from '@renderer/model/request.model';
import { ClickhousePluginService } from '@renderer/services/plugin/clickhouse.plugin.service';
+import { DatasourceModel } from '@renderer/model/datasource.model';
@Component({
selector: 'app-home',
@@ -12,21 +13,23 @@ import { ClickhousePluginService } from '@renderer/services/plugin/clickhouse.pl
})
export class HomeComponent implements OnInit {
version: string = PackageUtils.get('version');
- dataSources: any[];
+ dataSources: DatasourceModel[] = new Array();
chartsConfig: ChartsModel[] = new Array();
chartsSkeleton: boolean[] = new Array();
constructor(private datasourceService: DatasourceService,
private queryService: QueryService,
private clickhousePluginService: ClickhousePluginService) {
- this.dataSources = this.datasourceService.getAll()?.data?.columns;
for (let i = 0; i < this.chartsConfig.length; i++) {
this.chartsSkeleton[i] = true;
}
}
ngOnInit() {
- this.handlerInitChart();
+ this.datasourceService.getAll().then(response => {
+ this.dataSources = response;
+ this.handlerInitChart();
+ });
}
handlerInitChart() {
diff --git a/src/renderer/app/pages/management/datasource/datasource.component.html b/src/renderer/app/pages/management/datasource/datasource.component.html
index 1011bf31..bd8858c9 100644
--- a/src/renderer/app/pages/management/datasource/datasource.component.html
+++ b/src/renderer/app/pages/management/datasource/datasource.component.html
@@ -1,5 +1,5 @@
-
@@ -11,7 +11,7 @@
-
+
{{'common.alias' | translate}}
@@ -45,7 +45,7 @@
nz-tooltip nzTooltipTitle="{{'common.delete' | translate}}"
[nzCancelText]="'common.cancel'|translate"
[nzOkText]="'common.ok'|translate"
- (nzOnConfirm)="handlerDelete(data.alias)">
+ (nzOnConfirm)="handlerDelete(data.id)">
();
actionType: ActionEnum;
actionSource: string;
validateForm!: FormGroup;
@@ -90,15 +89,19 @@ export class DatasourceComponent extends BaseComponent implements OnInit {
this.formInfo = new DatasourceModel();
break;
case ActionEnum.copy:
- this.formInfo = this.service.getAll(unique)?.data?.columns[0];
- this.formInfo.alias = StringUtils.format('{0} {1}',
- [this.translateService.instant('common.copy'), this.formInfo.alias]);
- this.handlerResetButton();
+ this.service.findByAlias(unique).then(response => {
+ this.formInfo = response;
+ this.formInfo.alias = StringUtils.format('{0} {1}',
+ [this.translateService.instant('common.copy'), this.formInfo.alias]);
+ this.handlerResetButton();
+ });
break;
case ActionEnum.update:
- this.formInfo = this.service.getAll(unique)?.data?.columns[0];
- this.showButton.next = false;
- this.handlerResetButton();
+ this.service.findByAlias(unique).then(response => {
+ this.formInfo = response;
+ this.showButton.next = false;
+ this.handlerResetButton();
+ });
}
}
@@ -132,39 +135,46 @@ export class DatasourceComponent extends BaseComponent implements OnInit {
}
handlerSave() {
- const request = new RequestModel();
- request.config = this.formInfo;
- const response = this.service.save(request);
- if (!response.status) {
- this.messageService.error(response.message);
- this.disabled.button = false;
- } else {
- this.messageService.success(response.message);
+ this.service.save(this.formInfo)
+ .then(() => {
+ this.messageService.success(this.translateService.instant('common.success'));
this.handlerCloseModal();
this.handlerGetAll();
- }
+ })
+ .catch(() => {
+ this.messageService.error(this.translateService.instant('common.error'));
+ this.disabled.button = false;
+ });
this.loading.button = false;
}
handlerGetAll() {
- this.tableDetails = this.service.getAll().data;
+ this.service.getAll()
+ .then(response => {
+ this.tableDetails = response;
+ })
+ .catch(() => {
+ this.messageService.error(this.translateService.instant('common.error'));
+ });
}
- handlerDelete(unique: string) {
- const response = this.service.delete(unique);
- this.messageService.success(response.message);
- this.handlerGetAll();
+ handlerDelete(id: number) {
+ this.service.delete(id).then(() => {
+ this.messageService.success(this.translateService.instant('common.success'));
+ this.handlerGetAll();
+ }).catch(error => {
+ this.messageService.error(error);
+ });
}
handlerUpdate() {
- const response = this.service.update(this.actionSource, this.formInfo);
- if (!response.status) {
- this.messageService.error(response.message);
- } else {
- this.messageService.success(response.message);
+ this.service.update(this.formInfo).then(() => {
+ this.messageService.success(this.translateService.instant('common.success'));
this.handlerCloseModal();
this.handlerGetAll();
- }
+ }).catch(error => {
+ this.messageService.error(error);
+ });
}
handlerProcess() {
diff --git a/src/renderer/app/pages/management/metadata/metadata.component.ts b/src/renderer/app/pages/management/metadata/metadata.component.ts
index 55ccb412..97555388 100644
--- a/src/renderer/app/pages/management/metadata/metadata.component.ts
+++ b/src/renderer/app/pages/management/metadata/metadata.component.ts
@@ -46,16 +46,24 @@ export class MetadataComponent extends BaseComponent implements OnInit {
private messageService: NzMessageService,
private contextMenuService: ContextMenuService) {
super();
- const datasourceConfigs = this.dataSourceService.getAll()?.data?.columns.map(k => {
- const configModel = new ConfigModel();
- configModel.key = k.alias;
- configModel.value = k.alias;
- configModel.title = k.alias;
- configModel.type = TypeEnum.disk;
- configModel.disabled = k.status ? false : true;
- return configModel;
+ this.dataSourceService.getAll().then(response => {
+ const datasourceConfigs = response.map(k => {
+ const configModel = new ConfigModel();
+ configModel.key = k.alias;
+ configModel.value = k.alias;
+ configModel.title = k.alias;
+ configModel.type = TypeEnum.disk;
+ configModel.disabled = k.status ? false : true;
+ if (configModel.disabled) {
+ configModel.isLeaf = true;
+ }
+ return configModel;
+ });
+ this.nodes = datasourceConfigs;
+ })
+ .catch(error => {
+ this.messageService.error(error.message);
});
- this.nodes = datasourceConfigs;
this.outerHeight = window.outerHeight;
}
@@ -66,8 +74,10 @@ export class MetadataComponent extends BaseComponent implements OnInit {
if (!origin.level) {
this.rootNode = origin;
}
- this.contextMenus = this.contextMenuService.getContextMenu(origin.type);
- this.nzContextMenuService.create($event, menu);
+ if (!origin.disabled) {
+ this.contextMenus = this.contextMenuService.getContextMenu(origin.type);
+ this.nzContextMenuService.create($event, menu);
+ }
}
handlerContextMenuClick(menu: MenuModel): void {
@@ -79,7 +89,7 @@ export class MetadataComponent extends BaseComponent implements OnInit {
this.handlerContextMenuDialog(false);
}
- handlerContextMenuClosed(event: ConfigModel) {
+ async handlerContextMenuClosed(event: ConfigModel) {
this.handlerContextMenuDialog(false);
if (event.status) {
let node = event.currentNode;
@@ -93,7 +103,7 @@ export class MetadataComponent extends BaseComponent implements OnInit {
originNode.type = TypeEnum.server;
}
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.rootNode.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.rootNode.value);
this.metadataService.getChild(request, originNode).then(response => {
if (response.status) {
// clear old data
@@ -140,7 +150,11 @@ export class MetadataComponent extends BaseComponent implements OnInit {
}
}
- handlerNodeClick(event: NzFormatEmitEvent): void {
+ async handlerNodeClick(event: NzFormatEmitEvent) {
+ // Invalid node disables click function
+ if (event.node.origin.disabled) {
+ return;
+ }
// if (event.node.isSelected) {
this.loading.button = true;
if (event.node?.level === 0) {
@@ -156,7 +170,7 @@ export class MetadataComponent extends BaseComponent implements OnInit {
}
this.handlerLevel(this.selectNode);
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.rootNode.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.rootNode.value);
this.metadataService.getDiskUsedAndRatio(request, this.selectNode.origin).then(response => {
if (response.status) {
this.items = response.data.columns;
@@ -168,7 +182,11 @@ export class MetadataComponent extends BaseComponent implements OnInit {
// }
}
- handlerNodeLoad(event: NzFormatEmitEvent): void {
+ async handlerNodeLoad(event: NzFormatEmitEvent) {
+ // Invalid node disables click function
+ if (event.node.origin.disabled) {
+ return;
+ }
const node = event.node;
this.handlerLevel(node);
const originNode: any = event.node.origin;
@@ -177,7 +195,7 @@ export class MetadataComponent extends BaseComponent implements OnInit {
}
if (node?.getChildren().length === 0 && node?.isExpanded) {
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.rootNode.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.rootNode.value);
this.metadataService.getChild(request, originNode).then(response => {
if (response.status) {
node.addChildren(TreeUtils.builderTreeNode(response.data.columns, originNode.type));
diff --git a/src/renderer/app/pages/management/metadata/metadata.module.ts b/src/renderer/app/pages/management/metadata/metadata.module.ts
index 1c0d8c01..bdd855b0 100644
--- a/src/renderer/app/pages/management/metadata/metadata.module.ts
+++ b/src/renderer/app/pages/management/metadata/metadata.module.ts
@@ -39,6 +39,7 @@ import { TableTtlRemoveComponent } from '@renderer/components/table/ttl/remove/t
import { CommonDatabaseComponent } from '@renderer/components/database/common/common.database.component';
import { DatabaseRenameComponent } from '@renderer/components/database/rename/database.rename.component';
import { ColumnCreateComponent } from '@renderer/components/column/create/column.create.component';
+import { CommentColumnComponent } from '@renderer/components/column/comment/column.comment.component';
const MANAGEMENT_METADATA_ROUTES: Routes = [
{path: '', component: MetadataComponent}
@@ -81,7 +82,8 @@ const MANAGEMENT_METADATA_ROUTES: Routes = [
TableTtlRemoveComponent,
CommonDatabaseComponent,
DatabaseRenameComponent,
- ColumnCreateComponent
+ ColumnCreateComponent,
+ CommentColumnComponent
],
providers: [
DatasourceService,
diff --git a/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts b/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts
index 2634b2b7..2120eb7d 100644
--- a/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts
+++ b/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts
@@ -27,14 +27,16 @@ export class MonitorConnectionComponent extends BaseComponent implements OnDestr
private monitorService: MonitorService,
private messageService: NzMessageService) {
super();
- this.dataSources = this.datasourceService.getAll()?.data?.columns;
+ this.datasourceService.getAll().then(response => {
+ this.dataSources = response;
+ });
}
- handlerSwitch() {
+ async handlerSwitch() {
this.loading.button = true;
this.models = null;
const request = new RequestModel();
- request.config = this.datasourceService.getAll(this.threshold.datasource)?.data?.columns[0];
+ request.config = await this.datasourceService.getByAliasAsync(this.threshold.datasource);
this.monitorService.getConnections(request).then(response => {
if (response.status) {
this.models = response.data;
diff --git a/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts b/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts
index 17486b2b..8c04e347 100644
--- a/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts
+++ b/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts
@@ -26,17 +26,19 @@ export class MonitorMutationsComponent extends BaseComponent implements OnDestro
chartsConfig: ChartsModel;
constructor(private datasourceService: DatasourceService,
- private monitorService: MonitorService,
- private messageService: NzMessageService) {
+ private monitorService: MonitorService,
+ private messageService: NzMessageService) {
super();
- this.dataSources = this.datasourceService.getAll()?.data?.columns;
+ this.datasourceService.getAll().then(response => {
+ this.dataSources = response;
+ });
}
- handlerSwitch() {
+ async handlerSwitch() {
this.loading.button = true;
this.processors = null;
const request = new RequestModel();
- request.config = this.datasourceService.getAll(this.threshold.datasource)?.data?.columns[0];
+ request.config = await this.datasourceService.getByAliasAsync(this.threshold.datasource);
this.monitorService.getMutations(request).then(response => {
if (response.status) {
this.processors = response.data;
diff --git a/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts b/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts
index ddc44469..f11c1ef3 100644
--- a/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts
+++ b/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts
@@ -29,14 +29,16 @@ export class MonitorProcessorComponent extends BaseComponent implements OnDestro
private monitorService: MonitorService,
private messageService: NzMessageService) {
super();
- this.dataSources = this.datasourceService.getAll()?.data?.columns;
+ this.datasourceService.getAll().then(response => {
+ this.dataSources = response;
+ });
}
- handlerSwitch() {
+ async handlerSwitch() {
this.loading.button = true;
this.processors = null;
const request = new RequestModel();
- request.config = this.datasourceService.getAll(this.threshold.datasource)?.data?.columns[0];
+ request.config = await this.datasourceService.getByAliasAsync(this.threshold.datasource);
this.monitorService.getProcesses(request).then(response => {
if (response.status) {
this.processors = response.data;
diff --git a/src/renderer/app/pages/monitor/query/monitor.query.component.ts b/src/renderer/app/pages/monitor/query/monitor.query.component.ts
index e95c3ef9..2d7a74ff 100644
--- a/src/renderer/app/pages/monitor/query/monitor.query.component.ts
+++ b/src/renderer/app/pages/monitor/query/monitor.query.component.ts
@@ -23,17 +23,19 @@ export class MonitorQueryComponent extends BaseComponent {
queryDDL: string;
constructor(private datasourceService: DatasourceService,
- private monitorService: MonitorService,
- private messageService: NzMessageService) {
+ private monitorService: MonitorService,
+ private messageService: NzMessageService) {
super();
- this.dataSources = this.datasourceService.getAll()?.data?.columns;
+ this.datasourceService.getAll().then(response => {
+ this.dataSources = response;
+ });
}
- handlerSwitch() {
+ async handlerSwitch() {
this.loading.button = true;
this.processors = null;
const request = new RequestModel();
- request.config = this.datasourceService.getAll(this.threshold.datasource)?.data?.columns[0];
+ request.config = await this.datasourceService.getByAliasAsync(this.threshold.datasource);
this.monitorService.getSlowQuery(request, this.threshold.ranger).then(response => {
if (response.status) {
this.processors = response.data;
diff --git a/src/renderer/app/pages/query/query/query.component.html b/src/renderer/app/pages/query/query/query.component.html
index 8fbafade..83179d44 100644
--- a/src/renderer/app/pages/query/query/query.component.html
+++ b/src/renderer/app/pages/query/query/query.component.html
@@ -40,6 +40,13 @@
+
+
+
@@ -53,13 +60,24 @@
{{'common.add' | translate}} {{'common.editor' | translate}}
-
- {{'common.quick' | translate}} {{'common.query' | translate}}
+
+ {{'common.snippet'|translate}}
-
+
+ {{'common.action' | translate}}
+
+
-
- {{command.name}}
+
+ {{'common.quick' | translate}}{{'common.query' | translate}}
+
+
+ {{'common.code' | translate}}{{'common.snippet' | translate}}
@@ -103,3 +121,11 @@
(emitter)="handlerQuickQuery(true)"
(emitterValue)="handlerQuickQueryProcessor($event)">
+
+
+
+
diff --git a/src/renderer/app/pages/query/query/query.component.ts b/src/renderer/app/pages/query/query/query.component.ts
index b3dcd230..996983bf 100644
--- a/src/renderer/app/pages/query/query/query.component.ts
+++ b/src/renderer/app/pages/query/query/query.component.ts
@@ -7,7 +7,6 @@ import { QueryService } from '@renderer/services/query/query.service';
import { RequestModel } from '@renderer/model/request.model';
import { StringUtils } from '@renderer/utils/string.utils';
import { QueryHistoryModel } from '@renderer/model/query.history.model';
-import { Md5 } from 'ts-md5';
import { QueryHistoryService } from '@renderer/services/query/query.history.service';
import { NzMessageService } from 'ng-zorro-antd/message';
import { StateEnum } from '@renderer/enum/state.enum';
@@ -15,6 +14,8 @@ import { SqlUtils } from '@renderer/utils/sql.utils';
import { ResponseDataModel } from '@renderer/model/response.model';
import { SystemEditorModel } from '@renderer/model/system.model';
import { CommandModel } from '@renderer/model/command.model';
+import { SnippetModel } from '@renderer/model/snippet.model';
+import { ActionEnum } from '@renderer/enum/action.enum';
@Component({
selector: 'app-query',
@@ -37,6 +38,13 @@ export class QueryComponent extends BaseComponent implements AfterViewInit {
loadingContainers = [];
processorContainers = [];
containerSelected = 0;
+ codeSnippet = {
+ disabled: false,
+ value: SnippetModel
+ };
+ action: ActionEnum;
+ actionComponent = ActionEnum;
+ snippetValue: string;
constructor(private editorService: EditorService,
private datasourceService: DatasourceService,
@@ -46,7 +54,9 @@ export class QueryComponent extends BaseComponent implements AfterViewInit {
super();
const cache = this.editorService.get() === null ? new SystemEditorModel() : this.editorService.get();
this.editorConfig = Object.assign(this.editorService.getDefault(), cache);
- this.dataSources = this.datasourceService.getAll()?.data?.columns;
+ this.datasourceService.getAll().then(response => {
+ this.dataSources = response;
+ });
this.editorContainers.push('Editor ' + 1);
this.resultContainers.push('Editor ' + 1 + ' Result');
this.loadingContainers.push({loading: false});
@@ -98,35 +108,37 @@ export class QueryComponent extends BaseComponent implements AfterViewInit {
}
queryHistory.startTime = Date.parse(new Date().toString());
const request = new RequestModel();
- request.config = this.datasourceService.getAll(this.datasource)?.data?.columns[0];
- queryHistory.server = this.datasource;
- queryHistory.query = sql;
- this.processorContainers[this.containerSelected].icon = 'spinner fa-spin';
- this.processorContainers[this.containerSelected].color = 'cyan';
- this.queryService.getResponse(request, sql).then(response => {
- if (response.status) {
- queryHistory.state = StateEnum.success;
- this.processorContainers[this.containerSelected].icon = 'check-circle';
- this.processorContainers[this.containerSelected].color = '#87d068';
- if (response.data) {
- this.responseTableData[this.containerSelected] = response.data;
+ this.datasourceService.findByAlias(this.datasource).then(response => {
+ request.config = response;
+ queryHistory.server = this.datasource;
+ queryHistory.query = sql;
+ this.processorContainers[this.containerSelected].icon = 'spinner fa-spin';
+ this.processorContainers[this.containerSelected].color = 'cyan';
+ this.queryService.getResponse(request, sql).then(response => {
+ if (response.status) {
+ queryHistory.state = StateEnum.success;
+ this.processorContainers[this.containerSelected].icon = 'check-circle';
+ this.processorContainers[this.containerSelected].color = '#87d068';
+ if (response.data) {
+ this.responseTableData[this.containerSelected] = response.data;
+ } else {
+ this.messageService.success('Operation is successful!');
+ }
} else {
- this.messageService.success('Operation is successful!');
+ this.messageService.error(response.message);
+ queryHistory.message = response.message;
+ queryHistory.state = StateEnum.failure;
+ this.processorContainers[this.containerSelected].icon = 'times-circle';
+ this.processorContainers[this.containerSelected].color = '#f50';
}
- } else {
- this.messageService.error(response.message);
- queryHistory.message = response.message;
- queryHistory.state = StateEnum.failure;
- this.processorContainers[this.containerSelected].icon = 'times-circle';
- this.processorContainers[this.containerSelected].color = '#f50';
- }
- this.disabledButton.execute = false;
- this.loadingContainers[this.containerSelected].loading = false;
- this.loading.button = false;
- this.disabledButton.cancel = true;
- queryHistory.endTime = Date.parse(new Date().toString());
- queryHistory.elapsedTime = queryHistory.endTime - queryHistory.startTime;
- this.queryHistoryService.save(queryHistory);
+ this.disabledButton.execute = false;
+ this.loadingContainers[this.containerSelected].loading = false;
+ this.loading.button = false;
+ this.disabledButton.cancel = true;
+ queryHistory.endTime = Date.parse(new Date().toString());
+ queryHistory.elapsedTime = queryHistory.endTime - queryHistory.startTime;
+ this.queryHistoryService.save(queryHistory);
+ });
});
}
@@ -178,4 +190,27 @@ export class QueryComponent extends BaseComponent implements AfterViewInit {
handlerExecuteCommand(command: CommandModel) {
this.handlerExecute(command);
}
+
+ handlerCodeSnippet(close?: boolean) {
+ if (close) {
+ this.codeSnippet.disabled = false;
+ } else {
+ this.codeSnippet.disabled = true;
+ }
+ }
+
+ handlerCodeSnippetProcessor(sql?: string) {
+ const codeMirror = this.codeEditors.get(this.containerSelected)['codeMirror'];
+ codeMirror.setValue(sql);
+ }
+
+ handlerShowCreateSnippet(type: ActionEnum): void {
+ this.dialog.create = true;
+ this.action = type;
+ this.snippetValue = this.codeEditors.get(this.containerSelected)['codeMirror'].getValue();
+ }
+
+ handlerCloseCreateSnippet(event: boolean) {
+ this.dialog.create = false;
+ }
}
diff --git a/src/renderer/app/pages/query/query/query.module.ts b/src/renderer/app/pages/query/query/query.module.ts
index d252aa85..8cb592fb 100644
--- a/src/renderer/app/pages/query/query/query.module.ts
+++ b/src/renderer/app/pages/query/query/query.module.ts
@@ -14,6 +14,9 @@ import { QuickQueryComponent } from '@renderer/components/query/quick/quick.quer
import { QueryQuickService } from '@renderer/services/query/query.quick.service';
import { ServiceModule } from '@renderer/app/service.module';
import { CommonShareModule } from '@renderer/app/common-share.module';
+import { QuoteSnippetComponent } from '@renderer/components/snippet/quote/quote.snippet.component';
+import { SnippetService } from '@renderer/services/snippet/snippet.service';
+import { TableModule } from 'ngx-easy-table';
const QUERY_ROUTES: Routes = [
{path: '', component: QueryComponent}
@@ -28,19 +31,22 @@ const QUERY_ROUTES: Routes = [
NgZorroAntdModule,
ServiceModule,
RouterModule.forChild(QUERY_ROUTES),
- CommonShareModule
+ CommonShareModule,
+ TableModule
],
exports: [],
declarations: [
QueryComponent,
- QuickQueryComponent
+ QuickQueryComponent,
+ QuoteSnippetComponent
],
providers: [
EditorService,
DatasourceService,
QueryService,
QueryHistoryService,
- QueryQuickService
+ QueryQuickService,
+ SnippetService
]
})
export class QueryModule {
diff --git a/src/renderer/app/pages/query/snippet/snippet.component.html b/src/renderer/app/pages/query/snippet/snippet.component.html
new file mode 100644
index 00000000..dc430929
--- /dev/null
+++ b/src/renderer/app/pages/query/snippet/snippet.component.html
@@ -0,0 +1,77 @@
+
+
+
+
+ {{'common.add'|translate}}
+
+
+
+
+
+
+
+
+
+ {{'common.id'|translate}}
+ {{'common.name'|translate}}
+ {{'common.description'|translate}}
+ {{'common.code'|translate}}
+ {{'common.created'|translate}}
+ {{'common.updated'|translate}}
+ {{'common.action'|translate}}
+
+
+
+
+
+ {{data.id}}
+
+ {{data.name}}
+
+
+ {{data.description}}
+
+
+
+
+
+
+ {{data.created|amDateFormat:'YYYY-MM-DD HH:mm:ss'}}
+ {{data.updated|amDateFormat:'YYYY-MM-DD HH:mm:ss'}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/renderer/app/pages/query/snippet/snippet.component.ts b/src/renderer/app/pages/query/snippet/snippet.component.ts
new file mode 100644
index 00000000..1787d910
--- /dev/null
+++ b/src/renderer/app/pages/query/snippet/snippet.component.ts
@@ -0,0 +1,85 @@
+import { Component } from '@angular/core';
+import { BaseComponent } from '@renderer/app/base.component';
+import { NzModalService } from 'ng-zorro-antd/modal';
+import { NzMessageService } from 'ng-zorro-antd/message';
+import { TranslateService } from '@ngx-translate/core';
+import { Config, DefaultConfig } from 'ngx-easy-table';
+import { ActionEnum } from '@renderer/enum/action.enum';
+import { SnippetModel } from '@renderer/model/snippet.model';
+import { SystemEditorModel } from '@renderer/model/system.model';
+import { EditorService } from '@renderer/services/editor/editor.service';
+import { FormBuilder } from '@angular/forms';
+import { SnippetService } from '@renderer/services/snippet/snippet.service';
+
+@Component({
+ selector: 'app-query-snippet',
+ templateUrl: 'snippet.component.html'
+})
+export class SnippetComponent extends BaseComponent {
+ configuration: Config;
+ columns: any[] = new Array();
+ action: ActionEnum;
+ actionComponent = ActionEnum;
+ editorConfig: any;
+ selectRow: SnippetModel;
+
+ constructor(private editorService: EditorService,
+ private modal: NzModalService,
+ private formBuilder: FormBuilder,
+ private snippetService: SnippetService,
+ private messageService: NzMessageService,
+ private translateService: TranslateService) {
+ super();
+ this.configuration = {...DefaultConfig};
+ this.configuration.horizontalScroll = true;
+ this.configuration.orderEnabled = false;
+ this.configuration.paginationRangeEnabled = false;
+ this.configuration.fixedColumnWidth = true;
+ const cache = this.editorService.get() === null ? new SystemEditorModel() : this.editorService.get();
+ this.editorConfig = Object.assign(this.editorService.getDefault(), cache);
+ this.initialize();
+ }
+
+ initialize() {
+ this.snippetService.getAll()
+ .then(response => {
+ this.columns = response;
+ })
+ .catch(() => {
+ this.messageService.error(this.translateService.instant('common.error'));
+ });
+ }
+
+ handlerShowCreateSnippet(type: ActionEnum, data?: SnippetModel): void {
+ this.dialog.create = true;
+ this.action = type;
+ this.selectRow = data;
+ }
+
+ handlerCloseCreateSnippet(close?: boolean): void {
+ this.dialog.create = false;
+ if (close) {
+ this.initialize();
+ }
+ }
+
+ handlerShowModal(row: SnippetModel): void {
+ this.dialog.select = true;
+ this.selectRow = row;
+ }
+
+ handlerCloseModal(): void {
+ this.dialog.select = false;
+ }
+
+ handlerDelete(id: number) {
+ this.snippetService.delete(id)
+ .then(() => {
+ this.messageService.success(this.translateService.instant('common.success'));
+ this.initialize();
+ })
+ .catch(() => {
+ this.messageService.error(this.translateService.instant('common.error'));
+ });
+ }
+}
diff --git a/src/renderer/app/pages/query/snippet/snippet.module.ts b/src/renderer/app/pages/query/snippet/snippet.module.ts
new file mode 100644
index 00000000..c9875cfe
--- /dev/null
+++ b/src/renderer/app/pages/query/snippet/snippet.module.ts
@@ -0,0 +1,47 @@
+import { NgModule } from '@angular/core';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { RouterModule, Routes } from '@angular/router';
+import { TranslateModule, TranslateService } from '@ngx-translate/core';
+import { CommonModule } from '@angular/common';
+import { QueryHistoryService } from '@renderer/services/query/query.history.service';
+import { NgZorroAntdModule } from '@renderer/app/ng-zorro-antd.module';
+import { NzModalService } from 'ng-zorro-antd/modal';
+import { CommonShareModule } from '@renderer/app/common-share.module';
+import { EditorService } from '@renderer/services/editor/editor.service';
+import { SnippetComponent } from '@renderer/app/pages/query/snippet/snippet.component';
+import { TableModule } from 'ngx-easy-table';
+import { CodemirrorModule } from '@ctrl/ngx-codemirror';
+import { SnippetService } from '@renderer/services/snippet/snippet.service';
+import { MomentModule } from 'ngx-moment';
+
+const QUERY_ROUTES: Routes = [
+ {path: '', component: SnippetComponent}
+];
+
+@NgModule({
+ imports: [
+ FormsModule,
+ TranslateModule,
+ CommonModule,
+ NgZorroAntdModule,
+ RouterModule.forChild(QUERY_ROUTES),
+ CommonShareModule,
+ TableModule,
+ CodemirrorModule,
+ ReactiveFormsModule,
+ MomentModule
+ ],
+ exports: [],
+ declarations: [
+ SnippetComponent
+ ],
+ providers: [
+ TranslateService,
+ QueryHistoryService,
+ NzModalService,
+ EditorService,
+ SnippetService
+ ]
+})
+export class SnippetModule {
+}
diff --git a/src/renderer/app/pages/tools/migrte/migrte.component.ts b/src/renderer/app/pages/tools/migrte/migrte.component.ts
index 403993da..a4c7981d 100644
--- a/src/renderer/app/pages/tools/migrte/migrte.component.ts
+++ b/src/renderer/app/pages/tools/migrte/migrte.component.ts
@@ -10,108 +10,110 @@ import { StringUtils } from '@renderer/utils/string.utils';
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
- selector: 'app-tools-migrte',
- templateUrl: 'migrte.component.html'
+ selector: 'app-tools-migrte',
+ templateUrl: 'migrte.component.html'
})
export class MigrteComponent extends BaseComponent {
- dataSources: DatasourceModel[];
- source = { datasource: null, databases: [], database: null, tables: [], table: null };
- target = { datasource: null, databases: [], database: null, tables: [], table: null };
- tableSizeInfo: any;
+ dataSources: DatasourceModel[];
+ source = {datasource: null, databases: [], database: null, tables: [], table: null};
+ target = {datasource: null, databases: [], database: null, tables: [], table: null};
+ tableSizeInfo: any;
- constructor(private datasourceService: DatasourceService,
- private databaseService: DatabaseService,
- private messageService: NzMessageService,
- private tableService: TableService,
- private migrateService: MigrateService) {
- super();
- this.dataSources = this.datasourceService.getAll()?.data?.columns;
- }
-
- handlerSwitchSource(type: boolean) {
- this.databaseService.getAll(this.handlerRequest(type)).then(response => {
- if (response.status) {
- if (type) {
- this.source.databases = response.data.columns;
- } else {
- this.target.databases = response.data.columns;
- }
- } else {
- this.messageService.error(response.message);
- }
- });
- this.handlerValidate();
- }
+ constructor(private datasourceService: DatasourceService,
+ private databaseService: DatabaseService,
+ private messageService: NzMessageService,
+ private tableService: TableService,
+ private migrateService: MigrateService) {
+ super();
+ this.datasourceService.getAll().then(response => {
+ this.dataSources = response;
+ });
+ }
- handlerSwitchDatabase(type: boolean) {
- let database;
+ async handlerSwitchSource(type: boolean) {
+ this.databaseService.getAll(await this.handlerRequest(type)).then(response => {
+ if (response.status) {
if (type) {
- database = this.source.database;
+ this.source.databases = response.data.columns;
} else {
- database = this.target.database;
+ this.target.databases = response.data.columns;
}
- this.tableService.getAll(this.handlerRequest(type), database).then(response => {
- if (response.status) {
- if (type) {
- this.source.tables = response.data.columns;
- } else {
- this.target.tables = response.data.columns;
- }
- } else {
- this.messageService.error(response.message);
- }
- });
- this.handlerValidate();
- }
+ } else {
+ this.messageService.error(response.message);
+ }
+ });
+ this.handlerValidate();
+ }
- handlerRequest(type: boolean): RequestModel {
- const request = new RequestModel();
+ async handlerSwitchDatabase(type: boolean) {
+ let database;
+ if (type) {
+ database = this.source.database;
+ } else {
+ database = this.target.database;
+ }
+ this.tableService.getAll(await this.handlerRequest(type), database).then(response => {
+ if (response.status) {
if (type) {
- request.config = this.datasourceService.getAll(this.source.datasource)?.data?.columns[0];
+ this.source.tables = response.data.columns;
} else {
- request.config = this.datasourceService.getAll(this.target.datasource)?.data?.columns[0];
+ this.target.tables = response.data.columns;
}
- return request;
- }
+ } else {
+ this.messageService.error(response.message);
+ }
+ });
+ this.handlerValidate();
+ }
- handlerCheckTable() {
- const request = new RequestModel();
- request.config = this.datasourceService.getAll(this.source.datasource)?.data?.columns[0];
- this.tableService.getSize(request, this.source.database, this.source.table).then(response => {
- if (response.status) {
- if (response?.data?.columns.length > 0) {
- this.tableSizeInfo = response?.data?.columns[0];
- } else {
- this.tableSizeInfo = { flag: 0 };
- }
- } else {
- this.messageService.error(response.message);
- }
- })
+ async handlerRequest(type: boolean) {
+ const request = new RequestModel();
+ if (type) {
+ request.config = await this.datasourceService.getByAliasAsync(this.source.datasource);
+ } else {
+ request.config = await this.datasourceService.getByAliasAsync(this.target.datasource);
}
+ return request;
+ }
- handlerValidate(): boolean {
- if (StringUtils.isNotEmpty(this.source.datasource)
- && StringUtils.isNotEmpty(this.source.database)
- && StringUtils.isNotEmpty(this.source.table)
- && StringUtils.isNotEmpty(this.target.datasource)
- && StringUtils.isNotEmpty(this.target.database)
- && this.tableSizeInfo?.flag === 0
- ) {
- return false;
+ async handlerCheckTable() {
+ const request = new RequestModel();
+ request.config = await this.datasourceService.getByAliasAsync(this.source.datasource);
+ this.tableService.getSize(request, this.source.database, this.source.table).then(response => {
+ if (response.status) {
+ if (response?.data?.columns.length > 0) {
+ this.tableSizeInfo = response?.data?.columns[0];
+ } else {
+ this.tableSizeInfo = {flag: 0};
}
- return true;
+ } else {
+ this.messageService.error(response.message);
+ }
+ });
+ }
+
+ handlerValidate(): boolean {
+ if (StringUtils.isNotEmpty(this.source.datasource)
+ && StringUtils.isNotEmpty(this.source.database)
+ && StringUtils.isNotEmpty(this.source.table)
+ && StringUtils.isNotEmpty(this.target.datasource)
+ && StringUtils.isNotEmpty(this.target.database)
+ && this.tableSizeInfo?.flag === 0
+ ) {
+ return false;
}
+ return true;
+ }
- async handlerMigrate() {
- this.loading.button = true
- const response = await this.migrateService.migrate(this.source, this.target)
- if (response?.status) {
- this.loading.button = false;
- this.messageService.success(response?.message);
- } else {
- this.loading.button = false;
- this.messageService.error(response?.message);
- }
+ async handlerMigrate() {
+ this.loading.button = true;
+ const response = await this.migrateService.migrate(this.source, this.target);
+ if (response?.status) {
+ this.loading.button = false;
+ this.messageService.success(response?.message);
+ } else {
+ this.loading.button = false;
+ this.messageService.error(response?.message);
}
+ }
}
diff --git a/src/renderer/app/pages/tools/track/track.component.ts b/src/renderer/app/pages/tools/track/track.component.ts
index f4d8077b..f3d651a1 100644
--- a/src/renderer/app/pages/tools/track/track.component.ts
+++ b/src/renderer/app/pages/tools/track/track.component.ts
@@ -25,7 +25,9 @@ export class TrackComponent extends BaseComponent {
private messageService: NzMessageService,
private modal: NzModalService) {
super();
- this.dataSources = this.datasourceService.getAll()?.data?.columns;
+ this.datasourceService.getAll().then(response => {
+ this.dataSources = response;
+ });
}
handlerSearch(value: string) {
diff --git a/src/renderer/assets/i18n/en.json b/src/renderer/assets/i18n/en.json
index ad6fd5c0..e46bc20d 100644
--- a/src/renderer/assets/i18n/en.json
+++ b/src/renderer/assets/i18n/en.json
@@ -139,7 +139,16 @@
"remove": "Remove",
"status": "Status",
"success": "Success",
- "description": "Description"
+ "description": "Description",
+ "comment": "Comment",
+ "snippet": "Snippet",
+ "id": "ID",
+ "name": "Name",
+ "description": "Description",
+ "code": "Code",
+ "created": "Created",
+ "updated": "Updated",
+ "quote": "Quote"
},
"language": {
"english": "English",
@@ -170,7 +179,8 @@
"commitEveryBatch": "Commit Every Batch",
"threadPerConsumer": "Thread Per Consumer",
"maxTotal": "The maximum number of rows is displayed. If you manually enter limit, the configuration is overwritten. If 0 is set, the configuration does not take effect",
- "collection": "Please input collection"
+ "collection": "Please input collection",
+ "required": "This value cannot be empty, please enter"
},
"tooltip": {
"network": "Duration of accessing the remote server (in seconds)",
@@ -251,8 +261,15 @@
"noversion": "This is the latest version!",
"not_support_online": "Currently, online updates are not supported",
"table_grate_50": "Data tables larger than 50GB cannot be migrated",
+ "table_delete_grate_50": "Data tables larger than 50GB cannot be deleted",
"ttl": "When the time reaches, the system deletes data in the entire table based on the configured TTL",
"ttl_remove": "After the TTL configuration is removed, the system will not delete data",
- "only_one_column": "You cannot delete all columns in a data table, the table must contain at least one column"
+ "only_one_column": "You cannot delete all columns in a data table, the table must contain at least one column",
+ "delete_it": "We don't recommend that you delete it? This operation produces the following?",
+ "migrate_datasource": "The storage method of the data source has been modified. Please continue to use the original storage content after migrating the data.",
+ "migrate_data_success": "After the migration is successful, the source data will be cleaned up!"
+ },
+ "formatter": {
+ "migrate_data": "Need to migrate {0} data, please confirm whether to migrate?"
}
}
diff --git a/src/renderer/assets/i18n/zh.json b/src/renderer/assets/i18n/zh.json
index d89b5591..31a0fec7 100644
--- a/src/renderer/assets/i18n/zh.json
+++ b/src/renderer/assets/i18n/zh.json
@@ -138,7 +138,16 @@
"remove": "移除",
"status": "状态",
"success": "成功",
- "description": "描述"
+ "description": "描述",
+ "comment": "评论",
+ "snippet": "片段",
+ "id": "标记",
+ "name": "名称",
+ "description": "描述",
+ "code": "代码",
+ "created": "创建",
+ "updated": "更新",
+ "quote": "引用"
},
"language": {
"english": "英语",
@@ -171,7 +180,8 @@
"maxTotal": "返回查询最大行数,用户手动填写limit将覆盖该配置,如果设置0则该配置不生效",
"collection": "Please input collection",
"options": "Options",
- "ttl": "TTL"
+ "ttl": "TTL",
+ "required": "该值不能为空, 请输入"
},
"tooltip": {
"network": "访问远程服务器的时间(以秒为单位)",
@@ -252,8 +262,15 @@
"noversion": "当前已经是最新版本",
"not_support_online": "当前暂不支持在线更新",
"table_grate_50": "暂不支持迁移大于50GB数据表",
+ "table_delete_grate_50": "暂不支持删除大于50GB数据表",
"ttl": "达到时间后,系统将根据配置的TTL值,删除整个表中的数据",
"ttl_remove": "TTL配置移除后, 系统将不会在对数据进行删除操作",
- "only_one_column": "不能删除数据表中的所有列, 该数据表必须至少包含一列"
+ "only_one_column": "不能删除数据表中的所有列, 该数据表必须至少包含一列",
+ "delete_it": "我们不建议你删除它?这个操作会产生以下结果?",
+ "migrate_datasource": "数据源存储方式已经修改请迁移数据后继续使用原有存储内容",
+ "migrate_data_success": "迁移成功后源数据将被清理!"
+ },
+ "formatter": {
+ "migrate_data": "需要迁移{0}条数据, 请确认是否迁移?"
}
}
diff --git a/src/renderer/components/column/comment/column.comment.component.html b/src/renderer/components/column/comment/column.comment.component.html
new file mode 100644
index 00000000..123d55e7
--- /dev/null
+++ b/src/renderer/components/column/comment/column.comment.component.html
@@ -0,0 +1,22 @@
+
+
+
+
diff --git a/src/renderer/components/column/comment/column.comment.component.ts b/src/renderer/components/column/comment/column.comment.component.ts
new file mode 100644
index 00000000..b648acc1
--- /dev/null
+++ b/src/renderer/components/column/comment/column.comment.component.ts
@@ -0,0 +1,64 @@
+import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core';
+import { BaseComponent } from '@renderer/app/base.component';
+import { ConfigModel } from '@renderer/model/config.model';
+import { DatabaseModel } from '@renderer/model/database.model';
+import { RequestModel } from '@renderer/model/request.model';
+import { ColumnService } from '@renderer/services/management/column.service';
+import { DatasourceService } from '@renderer/services/management/datasource.service';
+import { NzMessageService } from 'ng-zorro-antd/message';
+import { StringUtils } from '@renderer/utils/string.utils';
+
+@Component({
+ selector: 'app-component-comment-column',
+ templateUrl: './column.comment.component.html'
+})
+export class CommentColumnComponent extends BaseComponent implements AfterViewInit {
+ @Input()
+ config: ConfigModel;
+ @Input()
+ value: string;
+ @Input()
+ database: string;
+ @Input()
+ table: string;
+ @Output()
+ emitter = new EventEmitter();
+ inputValue: string;
+
+ constructor(private dataSourceService: DatasourceService,
+ private columnService: ColumnService,
+ private messageService: NzMessageService) {
+ super();
+ }
+
+ handlerValidate() {
+ if (StringUtils.isNotEmpty(this.inputValue)) {
+ this.disabled.button = false;
+ } else {
+ this.disabled.button = true;
+ }
+ }
+
+ async handlerAddComment() {
+ this.loading.button = true;
+ const request = new RequestModel();
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
+ const _value = new DatabaseModel();
+ _value.database = this.database;
+ _value.table = this.table;
+ _value.name = this.value;
+ this.columnService.comment(request, _value, this.inputValue).then(response => {
+ if (response.status) {
+ this.messageService.success(response.message);
+ this.config.status = false;
+ this.emitter.emit(this.config);
+ } else {
+ this.messageService.error(response.message);
+ }
+ this.loading.button = false;
+ });
+ }
+
+ ngAfterViewInit(): void {
+ }
+}
diff --git a/src/renderer/components/column/common/common.column.component.html b/src/renderer/components/column/common/common.column.component.html
index 77e162e6..6ba9f2c5 100644
--- a/src/renderer/components/column/common/common.column.component.html
+++ b/src/renderer/components/column/common/common.column.component.html
@@ -16,5 +16,9 @@
[value]="value?.origin?.key" [database]="database" [table]="table"
(emitter)="handlerEmitter($event)">
+
+
diff --git a/src/renderer/components/column/create/column.create.component.ts b/src/renderer/components/column/create/column.create.component.ts
index 84e3ce8d..3580c882 100644
--- a/src/renderer/components/column/create/column.create.component.ts
+++ b/src/renderer/components/column/create/column.create.component.ts
@@ -108,10 +108,10 @@ export class ColumnCreateComponent extends BaseComponent {
}
}
- handlerSave() {
+ async handlerSave() {
this.loading.button = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
const _value = new DatabaseModel();
_value.database = this.database;
_value.table = this.table;
diff --git a/src/renderer/components/column/delete/column.delete.component.ts b/src/renderer/components/column/delete/column.delete.component.ts
index 9fbb7142..a18f8966 100644
--- a/src/renderer/components/column/delete/column.delete.component.ts
+++ b/src/renderer/components/column/delete/column.delete.component.ts
@@ -39,10 +39,10 @@ export class DeleteColumnComponent extends BaseComponent implements AfterViewIni
}
}
- handlerDelete() {
+ async handlerDelete() {
this.loading.button = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
const _value = new DatabaseModel();
_value.database = this.database;
_value.table = this.table;
@@ -64,9 +64,9 @@ export class DeleteColumnComponent extends BaseComponent implements AfterViewIni
this.handlerValidate();
}
- ngAfterViewInit(): void {
+ async ngAfterViewInit() {
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
const _value = new DatabaseModel();
_value.database = this.database;
_value.table = this.table;
diff --git a/src/renderer/components/column/preview/column.preview.component.html b/src/renderer/components/column/preview/column.preview.component.html
index 79e43dba..97b28416 100644
--- a/src/renderer/components/column/preview/column.preview.component.html
+++ b/src/renderer/components/column/preview/column.preview.component.html
@@ -1,17 +1,17 @@
-
-
- {{'common.database'|translate}}
-
- {{database}}
-
-
-
- {{'common.table'|translate}}
-
- {{table}}
-
-
-
-
-
\ No newline at end of file
+
+
+ {{'common.database'|translate}}
+
+ {{database}}
+
+
+
+ {{'common.table'|translate}}
+
+ {{table}}
+
+
+
+ 0" [value]="tableData">
+
diff --git a/src/renderer/components/column/preview/column.preview.component.ts b/src/renderer/components/column/preview/column.preview.component.ts
index 33e24b35..f24503f9 100644
--- a/src/renderer/components/column/preview/column.preview.component.ts
+++ b/src/renderer/components/column/preview/column.preview.component.ts
@@ -9,39 +9,39 @@ import { DatasourceService } from '@renderer/services/management/datasource.serv
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
- selector: 'app-component-preview-column',
- templateUrl: './column.preview.component.html'
+ selector: 'app-component-preview-column',
+ templateUrl: './column.preview.component.html'
})
export class PreviewColumnComponent extends BaseComponent implements AfterViewInit {
- @Input()
- config: ConfigModel;
- @Input()
- value: string;
- @Input()
- database: string;
- @Input()
- table: string;
- tableData: ResponseDataModel;
+ @Input()
+ config: ConfigModel;
+ @Input()
+ value: string;
+ @Input()
+ database: string;
+ @Input()
+ table: string;
+ tableData: ResponseDataModel;
- constructor(private dataSourceService: DatasourceService,
- private columnService: ColumnService,
- private messageService: NzMessageService) {
- super();
- }
+ constructor(private dataSourceService: DatasourceService,
+ private columnService: ColumnService,
+ private messageService: NzMessageService) {
+ super();
+ }
- ngAfterViewInit(): void {
- const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
- const _value = new DatabaseModel();
- _value.database = this.database;
- _value.table = this.table;
- _value.name = this.value;
- this.columnService.getPreview(request, _value).then(response => {
- if (response.status) {
- this.tableData = response.data;
- } else {
- this.messageService.error(response.message);
- }
- });
- }
+ async ngAfterViewInit() {
+ const request = new RequestModel();
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
+ const _value = new DatabaseModel();
+ _value.database = this.database;
+ _value.table = this.table;
+ _value.name = this.value;
+ this.columnService.getPreview(request, _value).then(response => {
+ if (response.status) {
+ this.tableData = response.data;
+ } else {
+ this.messageService.error(response.message);
+ }
+ });
+ }
}
diff --git a/src/renderer/components/column/rename/column.rename.component.ts b/src/renderer/components/column/rename/column.rename.component.ts
index 08082475..2f86c4f4 100644
--- a/src/renderer/components/column/rename/column.rename.component.ts
+++ b/src/renderer/components/column/rename/column.rename.component.ts
@@ -39,10 +39,10 @@ export class RenameColumnComponent extends BaseComponent {
}
}
- handlerRename() {
+ async handlerRename() {
this.loading.button = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
const _value = new DatabaseModel();
_value.database = this.database;
_value.table = this.table;
diff --git a/src/renderer/components/database/basic/database.basic.component.ts b/src/renderer/components/database/basic/database.basic.component.ts
index 1314818c..f6874af6 100644
--- a/src/renderer/components/database/basic/database.basic.component.ts
+++ b/src/renderer/components/database/basic/database.basic.component.ts
@@ -84,9 +84,9 @@ export class DatabaseBasicComponent extends BaseComponent {
this.handlerValidate();
}
- handlerComplete(): void {
+ async handlerComplete() {
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
this.metadataService.createDatabase(request, this.configure).then(response => {
if (response.status) {
this.messageService.success(response.message);
diff --git a/src/renderer/components/database/drop/database.drop.component.ts b/src/renderer/components/database/drop/database.drop.component.ts
index fb3e98a7..dae5bb8f 100644
--- a/src/renderer/components/database/drop/database.drop.component.ts
+++ b/src/renderer/components/database/drop/database.drop.component.ts
@@ -48,10 +48,10 @@ export class DatabaseDropComponent extends BaseComponent implements AfterViewIni
}, 0);
}
- handlerCheckTables() {
+ async handlerCheckTables() {
this.getTables = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
this.databaseService.getTables(request, this.value).then(response => {
if (response.status) {
this.tables = response.data;
@@ -76,10 +76,10 @@ export class DatabaseDropComponent extends BaseComponent implements AfterViewIni
}
}
- handlerDelete() {
+ async handlerDelete() {
this.loading.button = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
this.metadataService.delete(request, this.value).then(response => {
if (response.status) {
this.messageService.success(response.message);
@@ -99,10 +99,10 @@ export class DatabaseDropComponent extends BaseComponent implements AfterViewIni
this.handlerValidate();
}
- handlerDeleteTable(table: any) {
+ async handlerDeleteTable(table: any) {
this.deleteTable = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
const _value = new DatabaseModel();
_value.database = this.value;
_value.name = table.name;
diff --git a/src/renderer/components/database/rename/database.rename.component.ts b/src/renderer/components/database/rename/database.rename.component.ts
index 0330db11..24a5b4cb 100644
--- a/src/renderer/components/database/rename/database.rename.component.ts
+++ b/src/renderer/components/database/rename/database.rename.component.ts
@@ -1,10 +1,8 @@
import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core';
import { BaseComponent } from '@renderer/app/base.component';
import { ConfigModel } from '@renderer/model/config.model';
-import { DatabaseModel } from '@renderer/model/database.model';
import { RequestModel } from '@renderer/model/request.model';
import { DatasourceService } from '@renderer/services/management/datasource.service';
-import { TableService } from '@renderer/services/management/table.service';
import { StringUtils } from '@renderer/utils/string.utils';
import { NzMessageService } from 'ng-zorro-antd/message';
import { DatabaseService } from '@renderer/services/management/database.service';
@@ -35,10 +33,10 @@ export class DatabaseRenameComponent extends BaseComponent implements AfterViewI
}, 0);
}
- handlerCheckDatabaseStatus() {
+ async handlerCheckDatabaseStatus() {
this.checkStatus = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
this.databaseService.getDatabase(request, this.value)
.then(response => {
if (response.status) {
@@ -57,10 +55,10 @@ export class DatabaseRenameComponent extends BaseComponent implements AfterViewI
}
}
- handlerRename() {
+ async handlerRename() {
this.loading.button = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
this.databaseService.rename(request, this.value, this.inputValue)
.then(response => {
if (response.status) {
diff --git a/src/renderer/components/database/structure/database.structure.component.ts b/src/renderer/components/database/structure/database.structure.component.ts
index 1253e879..0c9ff8a8 100644
--- a/src/renderer/components/database/structure/database.structure.component.ts
+++ b/src/renderer/components/database/structure/database.structure.component.ts
@@ -37,7 +37,7 @@ export class DatabaseStructureComponent extends BaseComponent implements AfterVi
ngAfterViewInit(): void {
// eslint-disable-next-line max-len
- // Fix ERROR Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'
+ // Fix Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'
setTimeout(() => {
this.handlerInitialize();
}, 0);
@@ -48,10 +48,10 @@ export class DatabaseStructureComponent extends BaseComponent implements AfterVi
this.emitter.emit(this.visible);
}
- handlerInitialize() {
+ async handlerInitialize() {
this.loading.button = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
this.metadataService.getDatabaseDDL(request, this.value).then(response => {
if (response.status) {
this.structure = response?.data?.columns[0]?.statement;
diff --git a/src/renderer/components/query/quick/quick.query.component.html b/src/renderer/components/query/quick/quick.query.component.html
index 9532dbf2..84228150 100644
--- a/src/renderer/components/query/quick/quick.query.component.html
+++ b/src/renderer/components/query/quick/quick.query.component.html
@@ -9,7 +9,7 @@
- {{obj.alias}}
+ {{obj.alias}}
diff --git a/src/renderer/components/query/quick/quick.query.component.ts b/src/renderer/components/query/quick/quick.query.component.ts
index 382bce75..2301fab2 100644
--- a/src/renderer/components/query/quick/quick.query.component.ts
+++ b/src/renderer/components/query/quick/quick.query.component.ts
@@ -39,7 +39,9 @@ export class QuickQueryComponent extends BaseComponent {
private queryQuickService: QueryQuickService) {
super();
this.quickCommands = this.queryQuickService.getQuickAll();
- this.dataSourceSet = this.dataSourceService.getAll()?.data?.columns;
+ this.dataSourceService.getAll().then(response => {
+ this.dataSourceSet = response;
+ });
}
handlerCancel() {
@@ -50,35 +52,36 @@ export class QuickQueryComponent extends BaseComponent {
handlerChangeValue(quick: QuickEnum) {
this.table = null;
const request = new RequestModel();
- const datasourceInfo = this.dataSourceService.getAll(this.dataSource)?.data?.columns[0];
- request.config = datasourceInfo;
- switch (quick) {
- case QuickEnum.database:
- this.disabled.dialog = true;
- this.loading.database = true;
- this.databaseSet = [];
- this.queryService.getResponse(request, 'SHOW DATABASES').then(response => {
- if (response.status) {
- this.databaseSet = response.data.columns;
- } else {
- this.messageService.error(response.message);
- }
- this.loading.database = false;
- this.disabled.dialog = false;
- });
- break;
- case QuickEnum.table:
- this.tableSet = [];
- this.queryService.getResponse(request, 'SHOW TABLES FROM ' + this.database).then(response => {
- if (response.status) {
- this.tableSet = response.data.columns;
- } else {
- this.messageService.error(response.message);
- }
- this.loading.table = false;
- });
- break;
- }
+ this.dataSourceService.findByAlias(this.dataSource).then(response => {
+ request.config = response;
+ switch (quick) {
+ case QuickEnum.database:
+ this.disabled.dialog = true;
+ this.loading.database = true;
+ this.databaseSet = [];
+ this.queryService.getResponse(request, 'SHOW DATABASES').then(response => {
+ if (response.status) {
+ this.databaseSet = response.data.columns;
+ } else {
+ this.messageService.error(response.message);
+ }
+ this.loading.database = false;
+ this.disabled.dialog = false;
+ });
+ break;
+ case QuickEnum.table:
+ this.tableSet = [];
+ this.queryService.getResponse(request, 'SHOW TABLES FROM ' + this.database).then(response => {
+ if (response.status) {
+ this.tableSet = response.data.columns;
+ } else {
+ this.messageService.error(response.message);
+ }
+ this.loading.table = false;
+ });
+ break;
+ }
+ });
}
handlerQuickCommand(command: { name: string, value: string }) {
diff --git a/src/renderer/components/server/info/info.server.component.html b/src/renderer/components/server/info/info.server.component.html
index 2881c0c5..6abac4c0 100644
--- a/src/renderer/components/server/info/info.server.component.html
+++ b/src/renderer/components/server/info/info.server.component.html
@@ -1,5 +1,5 @@
diff --git a/src/renderer/components/server/info/info.server.component.ts b/src/renderer/components/server/info/info.server.component.ts
index 9b1f1242..9829cf35 100644
--- a/src/renderer/components/server/info/info.server.component.ts
+++ b/src/renderer/components/server/info/info.server.component.ts
@@ -30,17 +30,19 @@ export class InfoServerComponent extends BaseComponent implements AfterViewInit
this.emitter.emit(this.visible);
}
- ngAfterViewInit(): void {
- const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
- this.disabled.dialog = true;
- this.metadataService.getInfo(request).then(response => {
- if (response.status) {
- this.items = response.data;
- } else {
- this.messageService.error(response.message);
- }
- this.disabled.dialog = false;
- });
+ async ngAfterViewInit() {
+ setTimeout(async () => {
+ const request = new RequestModel();
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
+ this.disabled.dialog = true;
+ this.metadataService.getInfo(request).then(response => {
+ if (response.status) {
+ this.items = response.data;
+ } else {
+ this.messageService.error(response.message);
+ }
+ this.disabled.dialog = false;
+ });
+ }, 0);
}
}
diff --git a/src/renderer/components/snippet/create/create.snippet.component.html b/src/renderer/components/snippet/create/create.snippet.component.html
new file mode 100644
index 00000000..2260c70a
--- /dev/null
+++ b/src/renderer/components/snippet/create/create.snippet.component.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+ {{'common.name'|translate}}
+
+
+
+
+
+
+
+ {{'common.description'|translate}}
+
+
+
+
+
+
+
+
+ {{'common.snippet' | translate}}
+
+
+
+
+
+
+
+
+
+
+ {{'common.cancel'|translate}}
+ {{'common.save'|translate}}
+
+
+
diff --git a/src/renderer/components/snippet/create/create.snippet.component.ts b/src/renderer/components/snippet/create/create.snippet.component.ts
new file mode 100644
index 00000000..ea7dad49
--- /dev/null
+++ b/src/renderer/components/snippet/create/create.snippet.component.ts
@@ -0,0 +1,115 @@
+import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core';
+import { BaseComponent } from '@renderer/app/base.component';
+import { NzModalService } from 'ng-zorro-antd/modal';
+import { NzMessageService } from 'ng-zorro-antd/message';
+import { TranslateService } from '@ngx-translate/core';
+import { ActionEnum } from '@renderer/enum/action.enum';
+import { SnippetModel } from '@renderer/model/snippet.model';
+import { SystemEditorModel } from '@renderer/model/system.model';
+import { EditorService } from '@renderer/services/editor/editor.service';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { SnippetService } from '@renderer/services/snippet/snippet.service';
+import { StringUtils } from '@renderer/utils/string.utils';
+
+@Component({
+ selector: 'app-component-create-snippet',
+ templateUrl: 'create.snippet.component.html'
+})
+export class CreateSnippetComponent extends BaseComponent implements AfterViewInit {
+ @Input()
+ visible: boolean;
+ @Input()
+ action: ActionEnum;
+ @Input()
+ snippetValue?: string;
+ @Input()
+ snippetComponent?: SnippetModel;
+ @Output()
+ emitter = new EventEmitter();
+ snippet: SnippetModel;
+ editorConfig: any;
+ validateForm!: FormGroup;
+
+ constructor(private editorService: EditorService,
+ private modal: NzModalService,
+ private formBuilder: FormBuilder,
+ private snippetService: SnippetService,
+ private messageService: NzMessageService,
+ private translateService: TranslateService) {
+ super();
+ }
+
+ ngAfterViewInit(): void {
+ setTimeout(() => {
+ this.initialize();
+ }, 0);
+ }
+
+ initialize() {
+ const cache = this.editorService.get() === null ? new SystemEditorModel() : this.editorService.get();
+ this.editorConfig = Object.assign(this.editorService.getDefault(), cache);
+ this.handlerShowDrawer(this.action);
+ }
+
+ handlerRestValidator(): void {
+ this.validateForm = this.formBuilder.group({
+ name: [null, [Validators.required]],
+ description: [null, [Validators.required]],
+ code: [null, [Validators.required]]
+ });
+ }
+
+ handlerShowDrawer(type: ActionEnum): void {
+ this.handlerRestValidator();
+ switch (type) {
+ case ActionEnum.create:
+ this.snippet = new SnippetModel();
+ if (this.snippetValue) {
+ this.snippet.code = this.snippetValue;
+ }
+ break;
+ case ActionEnum.update:
+ this.snippet = this.snippetComponent;
+ }
+ }
+
+ handlerCloseDrawer(close?: boolean): void {
+ this.snippet = null;
+ this.validateForm = null;
+ if (StringUtils.isEmpty(close)) {
+ this.emitter.emit(false);
+ }
+ this.emitter.emit(close);
+ }
+
+ handlerSave(): void {
+ if (this.validateForm.valid) {
+ if (this.action === ActionEnum.create) {
+ this.snippetService.save(this.snippet)
+ .then(() => {
+ this.messageService.success(this.translateService.instant('common.success'));
+ this.handlerCloseDrawer(true);
+ })
+ .catch(() => {
+ this.messageService.error(this.translateService.instant('common.error'));
+ });
+ } else {
+ this.snippetService.update(this.snippet)
+ .then(() => {
+ this.messageService.success(this.translateService.instant('common.success'));
+ this.handlerCloseDrawer(true);
+ })
+ .catch(error => {
+ this.messageService.error(error);
+ });
+ }
+ } else {
+ Object.values(this.validateForm.controls).forEach(control => {
+ if (control.invalid) {
+ control.markAsDirty();
+ control.updateValueAndValidity({onlySelf: true});
+ }
+ });
+ }
+ }
+}
diff --git a/src/renderer/components/snippet/quote/quote.snippet.component.html b/src/renderer/components/snippet/quote/quote.snippet.component.html
new file mode 100644
index 00000000..9730ef07
--- /dev/null
+++ b/src/renderer/components/snippet/quote/quote.snippet.component.html
@@ -0,0 +1,51 @@
+
+
+
+
+
+ {{'common.id'|translate}}
+ {{'common.name'|translate}}
+ {{'common.description'|translate}}
+ {{'common.code'|translate}}
+ {{'common.action'|translate}}
+
+
+
+
+
+ {{data.id}}
+
+ {{data.name}}
+
+
+ {{data.description}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/renderer/components/snippet/quote/quote.snippet.component.ts b/src/renderer/components/snippet/quote/quote.snippet.component.ts
new file mode 100644
index 00000000..31cd099a
--- /dev/null
+++ b/src/renderer/components/snippet/quote/quote.snippet.component.ts
@@ -0,0 +1,65 @@
+import { BaseComponent } from '@renderer/app/base.component';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd/message';
+import { SnippetService } from '@renderer/services/snippet/snippet.service';
+import { SnippetModel } from '@renderer/model/snippet.model';
+import { TranslateService } from '@ngx-translate/core';
+import { SystemEditorModel } from '@renderer/model/system.model';
+import { EditorService } from '@renderer/services/editor/editor.service';
+
+@Component({
+ selector: 'app-component-quote-snippet',
+ templateUrl: './quote.snippet.component.html'
+})
+export class QuoteSnippetComponent extends BaseComponent {
+ @Input()
+ visible: boolean;
+ @Output()
+ emitter = new EventEmitter();
+ @Output()
+ emitterValue = new EventEmitter();
+ columns: SnippetModel[] = new Array();
+ toggledRows = new Set();
+ tableWidth = '100%';
+ editorConfig: any;
+
+ constructor(private snippetService: SnippetService,
+ private messageService: NzMessageService,
+ private editorService: EditorService,
+ private translateService: TranslateService) {
+ super();
+ const cache = this.editorService.get() === null ? new SystemEditorModel() : this.editorService.get();
+ this.editorConfig = Object.assign(this.editorService.getDefault(), cache);
+ this.editorConfig.readOnly = true;
+ this.initialize();
+ }
+
+ initialize() {
+ this.snippetService.getAll()
+ .then((snippets: SnippetModel[]) => {
+ this.columns = snippets;
+ })
+ .catch(() => {
+ this.messageService.error(this.translateService.instant('common.error'));
+ });
+ }
+
+ handlerCancel() {
+ this.visible = false;
+ this.emitter.emit(this.visible);
+ }
+
+ handlerRowToggled($event: MouseEvent, index: number): void {
+ if (this.toggledRows.has(index)) {
+ this.toggledRows.delete(index);
+ } else {
+ this.toggledRows.add(index);
+ }
+ this.tableWidth = document.getElementById('table')?.offsetWidth - 15 + 'px';
+ }
+
+ handlerRowSelectedQuote(snippet: SnippetModel): void {
+ this.emitterValue.emit(snippet.code);
+ this.handlerCancel();
+ }
+}
diff --git a/src/renderer/components/table/basic/basic.table.component.ts b/src/renderer/components/table/basic/basic.table.component.ts
index 04517dd2..a58ed174 100644
--- a/src/renderer/components/table/basic/basic.table.component.ts
+++ b/src/renderer/components/table/basic/basic.table.component.ts
@@ -30,7 +30,7 @@ export class BasicTableComponent extends BaseComponent implements AfterViewInit
ngAfterViewInit(): void {
setTimeout(() => {
- this.value.headers.forEach(column => {
+ this.value?.headers.forEach(column => {
this.headers.push({key: column.name, title: column.name});
});
}, 0);
diff --git a/src/renderer/components/table/clean/table.clean.component.ts b/src/renderer/components/table/clean/table.clean.component.ts
index 9a6b44d0..960dfa12 100644
--- a/src/renderer/components/table/clean/table.clean.component.ts
+++ b/src/renderer/components/table/clean/table.clean.component.ts
@@ -39,8 +39,8 @@ export class CleanTableComponent extends BaseComponent implements AfterViewInit
super();
}
- ngAfterViewInit(): void {
- this.tableService.getPartitions(this.handlerGetRequest(), this.handlerGetDatabaseModel())
+ async ngAfterViewInit() {
+ this.tableService.getPartitions(await this.handlerGetRequest(), this.handlerGetDatabaseModel())
.then(response => {
if (response.status) {
this.partitions = response.data.columns;
@@ -50,9 +50,9 @@ export class CleanTableComponent extends BaseComponent implements AfterViewInit
});
}
- handlerGetRequest(): RequestModel {
+ async handlerGetRequest(): Promise {
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
return request;
}
@@ -63,10 +63,10 @@ export class CleanTableComponent extends BaseComponent implements AfterViewInit
return _value;
}
- handlerValidate() {
+ async handlerValidate() {
if (ValidateUtils.validate(this.allowValue)) {
this.deletePartition = true;
- this.tableService.getPartitions(this.handlerGetRequest(),
+ this.tableService.getPartitions(await this.handlerGetRequest(),
this.handlerGetDatabaseModel(),
StringUtils.appendBackslash(this.allowValue.partition),
this.allowValue.logic)
@@ -88,9 +88,9 @@ export class CleanTableComponent extends BaseComponent implements AfterViewInit
}
}
- handlerClean(value: string) {
+ async handlerClean(value: string) {
this.loading.button = true;
- this.tableService.clean(this.handlerGetRequest(),
+ this.tableService.clean(await this.handlerGetRequest(),
this.handlerGetDatabaseModel(),
StringUtils.appendBackslash(value))
.then(response => {
diff --git a/src/renderer/components/table/create/table.create.component.ts b/src/renderer/components/table/create/table.create.component.ts
index 8ab54c81..e13d05a6 100644
--- a/src/renderer/components/table/create/table.create.component.ts
+++ b/src/renderer/components/table/create/table.create.component.ts
@@ -105,9 +105,9 @@ export class CreateTableComponent extends BaseComponent {
this.columns.length = 0;
}
- handlerComplete(): void {
+ async handlerComplete() {
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
this.configure.database = this.value;
this.tableService.createTable(request, this.configure, this.columns).then(response => {
if (response.status) {
diff --git a/src/renderer/components/table/delete/table.delete.component.html b/src/renderer/components/table/delete/table.delete.component.html
index 6ea5bc6b..1059fd67 100644
--- a/src/renderer/components/table/delete/table.delete.component.html
+++ b/src/renderer/components/table/delete/table.delete.component.html
@@ -1,21 +1,26 @@
+
+
+
+
+
+
-
+
- No rollback
+ {{'common.no_rollback'|translate}}
The metadata will be removed from the Clickhouse metadata
- No rollback
+ {{'common.no_rollback'|translate}}
All data files generated in this table will be removed from the relevant Clickhouse server file system
@@ -27,13 +32,15 @@
-
+
{{value}}
- {{'common.quicklyEnter'|translate}}
+ {{'common.quicklyEnter'|translate}}
diff --git a/src/renderer/components/table/delete/table.delete.component.ts b/src/renderer/components/table/delete/table.delete.component.ts
index bd7c06c1..a0eb090a 100644
--- a/src/renderer/components/table/delete/table.delete.component.ts
+++ b/src/renderer/components/table/delete/table.delete.component.ts
@@ -1,4 +1,4 @@
-import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core';
import { BaseComponent } from '@renderer/app/base.component';
import { ConfigModel } from '@renderer/model/config.model';
import { DatabaseModel } from '@renderer/model/database.model';
@@ -11,7 +11,7 @@ import { NzMessageService } from 'ng-zorro-antd/message';
selector: 'app-component-delete-table',
templateUrl: './table.delete.component.html'
})
-export class DeleteTableComponent extends BaseComponent {
+export class DeleteTableComponent extends BaseComponent implements AfterViewInit {
@Input()
config: ConfigModel;
@Input()
@@ -21,13 +21,30 @@ export class DeleteTableComponent extends BaseComponent {
@Output()
emitter = new EventEmitter();
inputValue: string;
+ tableInfo = {flag: 1};
constructor(private dataSourceService: DatasourceService,
private tableService: TableService,
+ private datasourceService: DatasourceService,
private messageService: NzMessageService) {
super();
}
+ ngAfterViewInit() {
+ setTimeout(async () => {
+ const request = new RequestModel();
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
+ this.tableService.getSize(request, this.database, this.value)
+ .then(response => {
+ if (response.status) {
+ this.tableInfo = response.data?.columns[0];
+ } else {
+ this.messageService.error(response.message);
+ }
+ });
+ }, 0);
+ }
+
handlerValidate() {
if (this.inputValue === this.value) {
this.disabled.button = false;
@@ -36,10 +53,10 @@ export class DeleteTableComponent extends BaseComponent {
}
}
- handlerDelete() {
+ async handlerDelete() {
this.loading.button = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
const _value = new DatabaseModel();
_value.database = this.database;
_value.name = this.value;
diff --git a/src/renderer/components/table/optimize/table.optimize.component.ts b/src/renderer/components/table/optimize/table.optimize.component.ts
index 4e8c4d66..904dfa19 100644
--- a/src/renderer/components/table/optimize/table.optimize.component.ts
+++ b/src/renderer/components/table/optimize/table.optimize.component.ts
@@ -1,4 +1,4 @@
-import { Component, EventEmitter, Input, Output, AfterViewInit } from '@angular/core';
+import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core';
import { BaseComponent } from '@renderer/app/base.component';
import { ConfigModel } from '@renderer/model/config.model';
import { DatabaseModel } from '@renderer/model/database.model';
@@ -9,66 +9,66 @@ import { StringUtils } from '@renderer/utils/string.utils';
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
- selector: 'app-component-optimize-table',
- templateUrl: './table.optimize.component.html'
+ selector: 'app-component-optimize-table',
+ templateUrl: './table.optimize.component.html'
})
export class OptimizeTableComponent extends BaseComponent implements AfterViewInit {
- @Input()
- config: ConfigModel;
- @Input()
- value: string;
- @Input()
- database: string;
- @Output()
- emitter = new EventEmitter();
- partitions: any[];
- partition: string;
- final: boolean;
+ @Input()
+ config: ConfigModel;
+ @Input()
+ value: string;
+ @Input()
+ database: string;
+ @Output()
+ emitter = new EventEmitter();
+ partitions: any[];
+ partition: string;
+ final: boolean;
- constructor(private dataSourceService: DatasourceService,
- private tableService: TableService,
- private messageService: NzMessageService) {
- super();
- }
+ constructor(private dataSourceService: DatasourceService,
+ private tableService: TableService,
+ private messageService: NzMessageService) {
+ super();
+ }
- ngAfterViewInit(): void {
- const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
- const _value = new DatabaseModel();
- _value.database = this.database;
- _value.name = this.value;
- this.tableService.getPartitions(request, _value).then(response => {
- if (response.status) {
- this.partitions = response.data.columns;
- } else {
- this.messageService.error(response.message);
- }
- });
- }
+ async ngAfterViewInit() {
+ const request = new RequestModel();
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
+ const _value = new DatabaseModel();
+ _value.database = this.database;
+ _value.name = this.value;
+ this.tableService.getPartitions(request, _value).then(response => {
+ if (response.status) {
+ this.partitions = response.data.columns;
+ } else {
+ this.messageService.error(response.message);
+ }
+ });
+ }
- handlerValidate() {
- if (StringUtils.isNotEmpty(this.partition)) {
- this.disabled.button = false;
- } else {
- this.disabled.button = true;
- }
+ handlerValidate() {
+ if (StringUtils.isNotEmpty(this.partition)) {
+ this.disabled.button = false;
+ } else {
+ this.disabled.button = true;
}
+ }
- handlerOptimize() {
- this.loading.button = true;
- const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
- const _value = new DatabaseModel();
- _value.database = this.database;
- _value.name = this.value;
- this.tableService.optimize(request, _value, this.partition, this.final).then(response => {
- if (response.status) {
- this.messageService.success(response.message);
- this.emitter.emit(true);
- } else {
- this.messageService.error(response.message);
- }
- this.loading.button = false;
- });
- }
+ async handlerOptimize() {
+ this.loading.button = true;
+ const request = new RequestModel();
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
+ const _value = new DatabaseModel();
+ _value.database = this.database;
+ _value.name = this.value;
+ this.tableService.optimize(request, _value, this.partition, this.final).then(response => {
+ if (response.status) {
+ this.messageService.success(response.message);
+ this.emitter.emit(true);
+ } else {
+ this.messageService.error(response.message);
+ }
+ this.loading.button = false;
+ });
+ }
}
diff --git a/src/renderer/components/table/preview/table.preview.component.html b/src/renderer/components/table/preview/table.preview.component.html
index 51483ea1..aa3485a9 100644
--- a/src/renderer/components/table/preview/table.preview.component.html
+++ b/src/renderer/components/table/preview/table.preview.component.html
@@ -1,17 +1,17 @@
-
-
- {{'common.database'|translate}}
-
- {{database}}
-
-
-
- {{'common.table'|translate}}
-
- {{value}}
-
-
-
-
-
\ No newline at end of file
+
+
+ {{'common.database'|translate}}
+
+ {{database}}
+
+
+
+ {{'common.table'|translate}}
+
+ {{value}}
+
+
+
+ 0" [value]="tableData">
+
diff --git a/src/renderer/components/table/preview/table.preview.component.ts b/src/renderer/components/table/preview/table.preview.component.ts
index 55b20b8a..d2cc7635 100644
--- a/src/renderer/components/table/preview/table.preview.component.ts
+++ b/src/renderer/components/table/preview/table.preview.component.ts
@@ -9,36 +9,36 @@ import { TableService } from '@renderer/services/management/table.service';
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
- selector: 'app-component-preview-table',
- templateUrl: './table.preview.component.html'
+ selector: 'app-component-preview-table',
+ templateUrl: './table.preview.component.html'
})
export class PreviewTableComponent extends BaseComponent implements AfterViewInit {
- @Input()
- config: ConfigModel;
- @Input()
- value: string;
- @Input()
- database: string;
- tableData: ResponseDataModel;
+ @Input()
+ config: ConfigModel;
+ @Input()
+ value: string;
+ @Input()
+ database: string;
+ tableData: ResponseDataModel;
- constructor(private dataSourceService: DatasourceService,
- private tableService: TableService,
- private messageService: NzMessageService) {
- super();
- }
+ constructor(private dataSourceService: DatasourceService,
+ private tableService: TableService,
+ private messageService: NzMessageService) {
+ super();
+ }
- ngAfterViewInit(): void {
- const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
- const _value = new DatabaseModel();
- _value.database = this.database;
- _value.name = this.value;
- this.tableService.getPreview(request, _value).then(response => {
- if (response.status) {
- this.tableData = response.data;
- } else {
- this.messageService.error(response.message);
- }
- });
- }
+ async ngAfterViewInit() {
+ const request = new RequestModel();
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
+ const _value = new DatabaseModel();
+ _value.database = this.database;
+ _value.name = this.value;
+ this.tableService.getPreview(request, _value).then(response => {
+ if (response.status) {
+ this.tableData = response.data;
+ } else {
+ this.messageService.error(response.message);
+ }
+ });
+ }
}
diff --git a/src/renderer/components/table/rename/table.rename.component.ts b/src/renderer/components/table/rename/table.rename.component.ts
index dfcf49fa..87a79bec 100644
--- a/src/renderer/components/table/rename/table.rename.component.ts
+++ b/src/renderer/components/table/rename/table.rename.component.ts
@@ -9,49 +9,49 @@ import { StringUtils } from '@renderer/utils/string.utils';
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
- selector: 'app-component-rename-table',
- templateUrl: './table.rename.component.html'
+ selector: 'app-component-rename-table',
+ templateUrl: './table.rename.component.html'
})
export class RenameTableComponent extends BaseComponent {
- @Input()
- config: ConfigModel;
- @Input()
- value: string;
- @Input()
- database: string;
- @Output()
- emitter = new EventEmitter();
- inputValue: string;
+ @Input()
+ config: ConfigModel;
+ @Input()
+ value: string;
+ @Input()
+ database: string;
+ @Output()
+ emitter = new EventEmitter();
+ inputValue: string;
- constructor(private dataSourceService: DatasourceService,
- private tableService: TableService,
- private messageService: NzMessageService) {
- super();
- }
+ constructor(private dataSourceService: DatasourceService,
+ private tableService: TableService,
+ private messageService: NzMessageService) {
+ super();
+ }
- handlerValidate() {
- if (StringUtils.isNotEmpty(this.inputValue) && this.inputValue !== this.value) {
- this.disabled.button = false;
- } else {
- this.disabled.button = true;
- }
+ handlerValidate() {
+ if (StringUtils.isNotEmpty(this.inputValue) && this.inputValue !== this.value) {
+ this.disabled.button = false;
+ } else {
+ this.disabled.button = true;
}
+ }
- handlerRename() {
- this.loading.button = true;
- const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
- const _value = new DatabaseModel();
- _value.database = this.database;
- _value.name = this.value;
- this.tableService.rename(request, _value, this.inputValue).then(response => {
- if (response.status) {
- this.messageService.success(response.message);
- this.emitter.emit(true);
- } else {
- this.messageService.error(response.message);
- }
- this.loading.button = false;
- });
- }
+ async handlerRename() {
+ this.loading.button = true;
+ const request = new RequestModel();
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
+ const _value = new DatabaseModel();
+ _value.database = this.database;
+ _value.name = this.value;
+ this.tableService.rename(request, _value, this.inputValue).then(response => {
+ if (response.status) {
+ this.messageService.success(response.message);
+ this.emitter.emit(true);
+ } else {
+ this.messageService.error(response.message);
+ }
+ this.loading.button = false;
+ });
+ }
}
diff --git a/src/renderer/components/table/structure/table.structure.component.ts b/src/renderer/components/table/structure/table.structure.component.ts
index 587f8300..f1f107f5 100644
--- a/src/renderer/components/table/structure/table.structure.component.ts
+++ b/src/renderer/components/table/structure/table.structure.component.ts
@@ -48,10 +48,10 @@ export class StructureTableComponent extends BaseComponent implements AfterViewI
this.emitter.emit(true);
}
- handlerInitialize() {
+ async handlerInitialize() {
this.loading.button = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
const _value = new DatabaseModel();
_value.database = this.database;
_value.name = this.value;
diff --git a/src/renderer/components/table/truncate/table.truncate.component.ts b/src/renderer/components/table/truncate/table.truncate.component.ts
index f2106314..7af1d7cf 100644
--- a/src/renderer/components/table/truncate/table.truncate.component.ts
+++ b/src/renderer/components/table/truncate/table.truncate.component.ts
@@ -36,10 +36,10 @@ export class TruncateTableComponent extends BaseComponent {
}
}
- handlerTruncate() {
+ async handlerTruncate() {
this.loading.button = true;
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
const _value = new DatabaseModel();
_value.database = this.database;
_value.name = this.value;
diff --git a/src/renderer/components/table/ttl/modify/table.ttl.modify.component.ts b/src/renderer/components/table/ttl/modify/table.ttl.modify.component.ts
index 9068c854..7164abd7 100644
--- a/src/renderer/components/table/ttl/modify/table.ttl.modify.component.ts
+++ b/src/renderer/components/table/ttl/modify/table.ttl.modify.component.ts
@@ -33,8 +33,8 @@ export class TableTtlModifyComponent extends BaseComponent implements AfterViewI
this.ttlConfig = new TableTtlModel();
}
- ngAfterViewInit(): void {
- this.tableService.getTimeColumns(this.handlerGetRequest(), this.handlerGetDatabaseModel())
+ async ngAfterViewInit() {
+ this.tableService.getTimeColumns(await this.handlerGetRequest(), this.handlerGetDatabaseModel())
.then(response => {
if (response.status) {
this.columns = response.data.columns;
@@ -44,9 +44,9 @@ export class TableTtlModifyComponent extends BaseComponent implements AfterViewI
});
}
- handlerGetRequest(): RequestModel {
+ async handlerGetRequest(): Promise {
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
return request;
}
@@ -79,11 +79,11 @@ export class TableTtlModifyComponent extends BaseComponent implements AfterViewI
}
}
- handlerSave() {
+ async handlerSave() {
this.loading.button = true;
this.ttlConfig.database = this.database;
this.ttlConfig.table = this.value;
- this.tableService.modifyTTL(this.handlerGetRequest(), this.ttlConfig)
+ this.tableService.modifyTTL(await this.handlerGetRequest(), this.ttlConfig)
.then(response => {
if (response.status) {
this.messageService.success(response.message);
diff --git a/src/renderer/components/table/ttl/remove/table.ttl.remove.component.ts b/src/renderer/components/table/ttl/remove/table.ttl.remove.component.ts
index 8da54255..edbb2767 100644
--- a/src/renderer/components/table/ttl/remove/table.ttl.remove.component.ts
+++ b/src/renderer/components/table/ttl/remove/table.ttl.remove.component.ts
@@ -6,7 +6,6 @@ import { NzMessageService } from 'ng-zorro-antd/message';
import { TableService } from '@renderer/services/management/table.service';
import { DatabaseModel } from '@renderer/model/database.model';
import { RequestModel } from '@renderer/model/request.model';
-import { StringUtils } from '@renderer/utils/string.utils';
import { TableTtlModel } from '@renderer/model/table/table.ttl.model';
@Component({
@@ -32,10 +31,10 @@ export class TableTtlRemoveComponent extends BaseComponent implements AfterViewI
this.ttlInstance = new TableTtlModel();
}
- ngAfterViewInit(): void {
+ async ngAfterViewInit() {
this.ttlInstance.database = this.database;
this.ttlInstance.table = this.value;
- this.tableService.getTTL(this.handlerGetRequest(), this.ttlInstance)
+ this.tableService.getTTL(await this.handlerGetRequest(), this.ttlInstance)
.then(response => {
if (response.status) {
this.ttlConfig = response.data.columns[0];
@@ -45,9 +44,9 @@ export class TableTtlRemoveComponent extends BaseComponent implements AfterViewI
});
}
- handlerGetRequest(): RequestModel {
+ async handlerGetRequest(): Promise {
const request = new RequestModel();
- request.config = this.dataSourceService.getAll(this.config.value)?.data?.columns[0];
+ request.config = await this.dataSourceService.getByAliasAsync(this.config.value);
return request;
}
@@ -58,9 +57,9 @@ export class TableTtlRemoveComponent extends BaseComponent implements AfterViewI
return _value;
}
- handlerRemove() {
+ async handlerRemove() {
this.loading.button = true;
- this.tableService.removeTTL(this.handlerGetRequest(), this.ttlInstance)
+ this.tableService.removeTTL(await this.handlerGetRequest(), this.ttlInstance)
.then(response => {
if (response.status) {
this.messageService.success(response.message);
diff --git a/src/renderer/config/operation.config.ts b/src/renderer/config/operation.config.ts
index 9bc927ce..2e4c3d33 100644
--- a/src/renderer/config/operation.config.ts
+++ b/src/renderer/config/operation.config.ts
@@ -51,7 +51,8 @@ export class OperationConfig {
{type: TypeEnum.column, actions: [OperationEnum.preview]},
{type: TypeEnum.column, actions: [OperationEnum.create]},
{type: TypeEnum.column, actions: [OperationEnum.delete]},
- {type: TypeEnum.column, actions: [OperationEnum.rename]}
+ {type: TypeEnum.column, actions: [OperationEnum.rename]},
+ {type: TypeEnum.column, actions: [OperationEnum.comment]}
];
opertions.push(column);
return opertions;
diff --git a/src/renderer/db/dexiedb.ts b/src/renderer/db/dexiedb.ts
index 28484e0f..61a6ed90 100644
--- a/src/renderer/db/dexiedb.ts
+++ b/src/renderer/db/dexiedb.ts
@@ -1,13 +1,20 @@
import Dexie, { Table } from 'dexie';
import { QueryHistoryModel } from '@renderer/model/query.history.model';
+import { SnippetModel } from '@renderer/model/snippet.model';
+import { DatasourceModel } from '@renderer/model/datasource.model';
export class DexieDb extends Dexie {
QueryHistoryTable: Table;
+ SnippetTable: Table;
+ DataSourceTable: Table;
constructor() {
super('dbm_db');
- this.version(1).stores({
- QueryHistoryTable: '++id,createdTime,startTime,endTime'
+ this.version(4)
+ .stores({
+ QueryHistoryTable: '++id,createdTime,startTime,endTime',
+ SnippetTable: '++id,name,created,updated',
+ DataSourceTable: '++id,name,alias,host,status,created,updated'
});
}
}
diff --git a/src/renderer/editor.theme.scss b/src/renderer/editor.theme.scss
index ef5f0920..c312e720 100644
--- a/src/renderer/editor.theme.scss
+++ b/src/renderer/editor.theme.scss
@@ -27,5 +27,13 @@
@import "~codemirror/theme/lesser-dark.css";
@import "~codemirror/theme/liquibyte.css";
@import "~codemirror/theme/lucario.css";
-//@import "~codemirror/theme/";
+@import "~codemirror/theme/material-darker.css";
+@import "~codemirror/theme/material-ocean.css";
+@import "~codemirror/theme/material-palenight.css";
+@import "~codemirror/theme/material.css";
+@import "~codemirror/theme/mbo.css";
+@import "~codemirror/theme/mdn-like.css";
+@import "~codemirror/theme/midnight.css";
+@import "~codemirror/theme/monokai.css";
+@import "~codemirror/theme/moxer.css";
//@import "~codemirror/theme/";
diff --git a/src/renderer/enum/editor/theme.enum.ts b/src/renderer/enum/editor/theme.enum.ts
index 1782a2e6..077293d4 100644
--- a/src/renderer/enum/editor/theme.enum.ts
+++ b/src/renderer/enum/editor/theme.enum.ts
@@ -27,5 +27,13 @@ export enum EditorThemeEnum {
juejin = ('juejin'),
'lesser-dark' = ('lesser-dark'),
liquibyte = ('liquibyte'),
- lucario = ('lucario')
+ lucario = ('lucario'),
+ 'material-darker' = ('material-darker'),
+ 'material-ocean' = ('material-ocean'),
+ 'material-palenight' = ('material-palenight'),
+ material = ('material'),
+ mbo = ('mbo'),
+ 'mdn-like' = ('mdn-like'),
+ midnight = ('midnight'),
+ moxer = ('moxer')
}
diff --git a/src/renderer/enum/operation.enum.ts b/src/renderer/enum/operation.enum.ts
index 4dd74b3f..7f80503a 100644
--- a/src/renderer/enum/operation.enum.ts
+++ b/src/renderer/enum/operation.enum.ts
@@ -9,6 +9,7 @@ export enum OperationEnum {
clean = ('clean'),
optimize = ('optimize'),
structure = ('structure'),
+ comment = ('comment'),
ttl = ('ttl'),
ttl_modify = ('ttl_modify'),
ttl_remove = ('ttl_remove')
diff --git a/src/renderer/job/datasource.job.ts b/src/renderer/job/datasource.job.ts
index 6c5b19cd..26e742d1 100644
--- a/src/renderer/job/datasource.job.ts
+++ b/src/renderer/job/datasource.job.ts
@@ -9,17 +9,19 @@ export class DatasourceJob {
}
checkHealth() {
- this.datasourceService.getAll()?.data?.columns.forEach(async element => {
- const request: RequestModel = new RequestModel();
- request.config = element;
- const response = await this.datasourceService.getResponse(request);
- element.status = response.status;
- if (StringUtils.isNotEmpty(response?.data?.columns)) {
- element.version = response.data.columns[0].version;
- } else {
- element.message = response.message;
- }
- this.datasourceService.update(element.alias, element);
+ this.datasourceService.getAll().then(response => {
+ response.forEach(async element => {
+ const request: RequestModel = new RequestModel();
+ request.config = element;
+ const response = await this.datasourceService.getResponse(request);
+ element.status = response.status;
+ if (StringUtils.isNotEmpty(response?.data?.columns)) {
+ element.version = response.data.columns[0].version;
+ } else {
+ element.message = response.message;
+ }
+ this.datasourceService.update(element);
+ });
});
}
}
diff --git a/src/renderer/model/column.model.ts b/src/renderer/model/column.model.ts
index 97ce2ad1..cf8bf9b3 100644
--- a/src/renderer/model/column.model.ts
+++ b/src/renderer/model/column.model.ts
@@ -1,6 +1,6 @@
export class ColumnModel {
name: string;
- type: string;
+ type = 'String';
description: string;
empty: boolean = false;
}
diff --git a/src/renderer/model/config.model.ts b/src/renderer/model/config.model.ts
index 9302854d..1bd99c7a 100644
--- a/src/renderer/model/config.model.ts
+++ b/src/renderer/model/config.model.ts
@@ -5,7 +5,7 @@ import { NzTreeNode } from 'ng-zorro-antd/core/tree/nz-tree-base-node';
export class ConfigModel extends BaseModel {
title: string;
- key: ConfigModel;
+ key: any;
value: string;
type: TypeEnum;
database: string;
diff --git a/src/renderer/model/datasource.model.ts b/src/renderer/model/datasource.model.ts
index b3be5e8e..d6cafae4 100644
--- a/src/renderer/model/datasource.model.ts
+++ b/src/renderer/model/datasource.model.ts
@@ -13,4 +13,6 @@ export class DatasourceModel {
type: string;
version: string;
maxTotal = 0;
+ created: Date;
+ updated: Date;
}
diff --git a/src/renderer/model/snippet.model.ts b/src/renderer/model/snippet.model.ts
new file mode 100644
index 00000000..89d9bad0
--- /dev/null
+++ b/src/renderer/model/snippet.model.ts
@@ -0,0 +1,8 @@
+export class SnippetModel {
+ id: number;
+ name: string;
+ description: string;
+ code: string;
+ created: Date;
+ updated: Date;
+}
diff --git a/src/renderer/services/management/column.service.ts b/src/renderer/services/management/column.service.ts
index a5f269d5..01b74480 100644
--- a/src/renderer/services/management/column.service.ts
+++ b/src/renderer/services/management/column.service.ts
@@ -29,6 +29,12 @@ export class ColumnService implements BaseService {
return this.getResponse(request, sql);
}
+ comment(request: RequestModel, value: DatabaseModel, comment: string): Promise {
+ const sql = StringUtils.format(`ALTER TABLE {0} COMMENT COLUMN {1} '{2}'`,
+ [SqlUtils.getTableName(value.database, value.table), value.name, StringUtils.appendBackslash(comment)]);
+ return this.getResponse(request, sql);
+ }
+
rename(request: RequestModel, value: DatabaseModel, newName: string): Promise {
const sql = StringUtils.format('ALTER TABLE {0} RENAME COLUMN {1} TO {2}', [SqlUtils.getTableName(value.database, value.table), value.name, newName]);
return this.getResponse(request, sql);
diff --git a/src/renderer/services/management/datasource.service.ts b/src/renderer/services/management/datasource.service.ts
index b5e6e345..3cda0cbe 100644
--- a/src/renderer/services/management/datasource.service.ts
+++ b/src/renderer/services/management/datasource.service.ts
@@ -1,16 +1,21 @@
import { BaseService } from '@renderer/services/base.service';
-import { ResponseDataModel, ResponseModel } from '@renderer/model/response.model';
+import { ResponseModel } from '@renderer/model/response.model';
import { RequestModel } from '@renderer/model/request.model';
import { UrlUtils } from '@renderer/utils/url.utils';
-import { RequestUtils } from '@renderer/utils/request.utils';
-import { StringUtils } from '@renderer/utils/string.utils';
import { DatasourceModel } from '@renderer/model/datasource.model';
import { HttpService } from '@renderer/services/http.service';
import { Injectable } from '@angular/core';
+import { PromiseExtended } from 'dexie';
+import { PersistenceService } from '@renderer/services/persistence.service';
+import { DexieDb } from '@renderer/db/dexiedb';
@Injectable()
-export class DatasourceService implements BaseService {
+export class DatasourceService extends PersistenceService implements BaseService {
+ private db: DexieDb;
+
constructor(private httpService: HttpService) {
+ super();
+ this.db = new DexieDb();
}
getResponse(request: RequestModel, sql?: string): Promise {
@@ -18,81 +23,51 @@ export class DatasourceService implements BaseService {
return this.httpService.post(UrlUtils.formatUrl(request), sql);
}
- save(request: RequestModel): ResponseModel {
- const response = new ResponseModel();
- const dsData = this.getAll(null).data;
- const dataSources = dsData.columns;
- const validateResponse = dataSources.filter(item => item.alias === request.config.alias);
- if (validateResponse.length > 0) {
- response.status = false;
- response.message = StringUtils.format('DataSource <{0}> Save Error, exists!',
- [request.config.alias]);
- } else {
- dataSources.push(request.config);
- localStorage.setItem(RequestUtils.KEY_DATASOURCE, JSON.stringify(dataSources));
- response.status = true;
- response.message = StringUtils.format('DataSource <{0}> Save Success!',
- [request.config.alias]);
- }
- return response;
- }
-
/**
* Get the local storage buffer data source
*
* @param uniqueName Data source name
*/
- getAll(uniqueName?: string): ResponseModel {
- const response = new ResponseModel();
- response.status = true;
- const dataSources = JSON.parse(localStorage.getItem(RequestUtils.KEY_DATASOURCE));
- const sources = dataSources === null ? [] : dataSources;
- const responseData = new ResponseDataModel();
- responseData.columns = sources;
- if (sources.length > 0) {
- const headers = [];
- Object.keys(sources[0]).forEach(key => {
- headers.push({
- name: key,
- type: 'String'
- });
- });
- responseData.headers = headers;
- if (StringUtils.isNotEmpty(uniqueName)) {
- responseData.columns = sources.filter(item => item.alias === uniqueName);
- }
- }
- response.data = responseData;
- return response;
+ getAll(): PromiseExtended {
+ return this.db.DataSourceTable
+ .orderBy('created')
+ .reverse()
+ .toArray();
+ }
+
+ delete(id: number): PromiseExtended {
+ return this.db.DataSourceTable.delete(id);
+ }
+
+ update(model: DatasourceModel): PromiseExtended {
+ model.updated = new Date();
+ return this.db.DataSourceTable.update(model.id, model);
+ }
+
+ clear(): boolean {
+ return false;
+ }
+
+ deleteById(id: number): boolean {
+ return false;
+ }
+
+ save(model: DatasourceModel): PromiseExtended {
+ model.created = new Date();
+ model.updated = new Date();
+ model.id = undefined;
+ return this.db.DataSourceTable.add(model);
}
- delete(unique: string): ResponseModel {
- const response = new ResponseModel();
- response.status = true;
- const dataSources = JSON.parse(localStorage.getItem(RequestUtils.KEY_DATASOURCE))
- .filter(item => item.alias !== unique);
- localStorage.setItem(RequestUtils.KEY_DATASOURCE, JSON.stringify(dataSources));
- response.message = StringUtils.format('Delete <{0}> success!',
- [unique]);
- return response;
+ findByAlias(alias: string): PromiseExtended {
+ return this.db.DataSourceTable.where('alias').equals(alias).first();
}
- update(unique: string, source: DatasourceModel) {
- const response = new ResponseModel();
- const dataSources = JSON.parse(localStorage.getItem(RequestUtils.KEY_DATASOURCE))
- .filter(item => item.alias !== unique);
- const validateResponse = dataSources.filter(item => item.alias === source.alias);
- if (validateResponse.length > 0) {
- response.message = StringUtils.format('DataSource <{0}> update error, exists!',
- [source.alias]);
- response.status = false;
- } else {
- dataSources.push(source);
- localStorage.setItem(RequestUtils.KEY_DATASOURCE, JSON.stringify(dataSources));
- response.message = StringUtils.format('Update <{0}> success!',
- [unique]);
- response.status = true;
- }
- return response;
+ async getByAliasAsync(alias: string): Promise {
+ let dataSource;
+ dataSource = await this.db.DataSourceTable.where('alias')
+ .equals(alias)
+ .toArray();
+ return dataSource.length > 0 ? dataSource[0] : new DatasourceModel();
}
}
diff --git a/src/renderer/services/management/table.service.ts b/src/renderer/services/management/table.service.ts
index 7d06127d..ecd15ae0 100644
--- a/src/renderer/services/management/table.service.ts
+++ b/src/renderer/services/management/table.service.ts
@@ -236,6 +236,7 @@ export class TableService implements BaseService {
break;
case PropertyEnum.name:
const substr = configure.properties
+ .filter(element => StringUtils.isNotEmpty(element.value))
.flatMap(element => StringUtils.format('\'{0}\'', [element.value]))
.join(', ');
sql = StringUtils.format('{0} {1}({2})', [prefix, configure.type, substr]);
diff --git a/src/renderer/services/persistence.service.ts b/src/renderer/services/persistence.service.ts
index 9d04663d..d2541a88 100644
--- a/src/renderer/services/persistence.service.ts
+++ b/src/renderer/services/persistence.service.ts
@@ -1,6 +1,6 @@
export abstract class PersistenceService {
public abstract save(model: any): any;
- public abstract getAll(): any[];
+ public abstract getAll(): any;
public abstract clear(): boolean;
public abstract deleteById(id: number): boolean;
}
diff --git a/src/renderer/services/snippet/snippet.service.ts b/src/renderer/services/snippet/snippet.service.ts
new file mode 100644
index 00000000..6e82e372
--- /dev/null
+++ b/src/renderer/services/snippet/snippet.service.ts
@@ -0,0 +1,51 @@
+import { BaseService } from '@renderer/services/base.service';
+import { RequestModel } from '@renderer/model/request.model';
+import { ResponseModel } from '@renderer/model/response.model';
+import { PersistenceService } from '@renderer/services/persistence.service';
+import { DexieDb } from '@renderer/db/dexiedb';
+import { SnippetModel } from '@renderer/model/snippet.model';
+import { PromiseExtended } from 'dexie';
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class SnippetService extends PersistenceService implements BaseService {
+ private db: DexieDb;
+
+ constructor() {
+ super();
+ this.db = new DexieDb();
+ }
+
+ getResponse(request: RequestModel, sql?: string): Promise {
+ return Promise.resolve(undefined);
+ }
+
+ save(model: SnippetModel): PromiseExtended {
+ model.created = new Date();
+ model.updated = new Date();
+ return this.db.SnippetTable.add(model);
+ }
+
+ update(model: SnippetModel): PromiseExtended {
+ return this.db.SnippetTable.update(model.id, model);
+ }
+
+ getAll(): PromiseExtended {
+ return this.db.SnippetTable
+ .orderBy('id')
+ .reverse()
+ .toArray();
+ }
+
+ clear(): boolean {
+ return false;
+ }
+
+ delete(id: number): PromiseExtended {
+ return this.db.SnippetTable.delete(id);
+ }
+
+ deleteById(id: number): boolean {
+ return false;
+ }
+}
diff --git a/src/renderer/services/tools/migrate.service.ts b/src/renderer/services/tools/migrate.service.ts
index 9de825c2..e36bc03a 100644
--- a/src/renderer/services/tools/migrate.service.ts
+++ b/src/renderer/services/tools/migrate.service.ts
@@ -10,104 +10,97 @@ import { TableService } from '../management/table.service';
@Injectable()
export class MigrateService implements BaseService {
- constructor(private httpService: HttpService,
- private tableService: TableService,
- private datasourceService: DatasourceService) {
- }
-
- getResponse(request: RequestModel, sql?: string): Promise {
- return this.httpService.post(UrlUtils.formatUrl(request), sql);
- }
-
- async migrate(source, target): Promise {
- let response
- let targetDatabase = target.database
- let targetTable = target.table
- if (StringUtils.isEmpty(targetDatabase)) {
- targetDatabase = source.database
- }
- if (StringUtils.isEmpty(targetTable)) {
- targetTable = source.table
- }
-
- const sourceRequest = new RequestModel()
- sourceRequest.config = this.datasourceService.getAll(source.datasource)?.data?.columns[0];
- const targetRequest = new RequestModel()
- targetRequest.config = this.datasourceService.getAll(target.datasource)?.data?.columns[0];
-
- // step 1: check table from target server
- let tableExists = false
- const cr = await this.tableService.check(targetRequest, targetDatabase, source.table)
- if (cr?.status) {
- if (cr.data?.columns.length > 0) {
- tableExists = true
- } else {
- response = cr;
- }
- }
-
- // step 2: get table ddl to source server
- let tableDdl
- const sql = StringUtils.format('SHOW CREATE TABLE `{0}`.`{1}`', [source.database, source.table])
- const gr = await this.getResponse(sourceRequest, sql)
- if (gr?.status) {
- if (gr.data?.columns.length > 0) {
- tableDdl = gr.data.columns[0].statement
- } else {
- response = gr;
- }
- }
-
- // step 3: replace table name
- if (StringUtils.isNotEmpty(tableDdl)) {
- tableDdl = tableDdl.replace(StringUtils.format('{0}.{1}', [source.database, source.table]),
- StringUtils.format('`{0}`.`{1}`', [targetDatabase, targetTable]))
- }
+ constructor(private httpService: HttpService,
+ private tableService: TableService,
+ private datasourceService: DatasourceService) {
+ }
- // step 4: create table on target server
- let tableCreate = false
- if (!tableExists) {
- const gqr = await this.getResponse(targetRequest, tableDdl)
- if (gqr?.status) {
- tableCreate = true
- } else {
- response = gqr;
- }
- }
+ getResponse(request: RequestModel, sql?: string): Promise {
+ return this.httpService.post(UrlUtils.formatUrl(request), sql);
+ }
- // step 5: migrate data
- if ((tableExists && !tableCreate) || (!tableExists && tableCreate)) {
- const sql = this.builderDDL(source, target, targetDatabase, targetTable, sourceRequest)
- response = await this.getResponse(targetRequest, sql)
- }
- return response;
+ async migrate(source, target): Promise {
+ let response;
+ let targetDatabase = target.database;
+ let targetTable = target.table;
+ if (StringUtils.isEmpty(targetDatabase)) {
+ targetDatabase = source.database;
}
+ if (StringUtils.isEmpty(targetTable)) {
+ targetTable = source.table;
+ }
+ const sourceRequest = new RequestModel();
+ sourceRequest.config = await this.datasourceService.getByAliasAsync(source.datasource);
+ const targetRequest = new RequestModel();
+ targetRequest.config = await this.datasourceService.getByAliasAsync(target.datasource);
+ // step 1: check table from target server
+ let tableExists = false;
+ const cr = await this.tableService.check(targetRequest, targetDatabase, source.table);
+ if (cr?.status) {
+ if (cr.data?.columns.length > 0) {
+ tableExists = true;
+ } else {
+ response = cr;
+ }
+ }
+ // step 2: get table ddl to source server
+ let tableDdl;
+ const sql = StringUtils.format('SHOW CREATE TABLE `{0}`.`{1}`', [source.database, source.table]);
+ const gr = await this.getResponse(sourceRequest, sql);
+ if (gr?.status) {
+ if (gr.data?.columns.length > 0) {
+ tableDdl = gr.data.columns[0].statement;
+ } else {
+ response = gr;
+ }
+ }
+ // step 3: replace table name
+ if (StringUtils.isNotEmpty(tableDdl)) {
+ tableDdl = tableDdl.replace(StringUtils.format('{0}.{1}', [source.database, source.table]),
+ StringUtils.format('`{0}`.`{1}`', [targetDatabase, targetTable]));
+ }
+ // step 4: create table on target server
+ let tableCreate = false;
+ if (!tableExists) {
+ const gqr = await this.getResponse(targetRequest, tableDdl);
+ if (gqr?.status) {
+ tableCreate = true;
+ } else {
+ response = gqr;
+ }
+ }
+ // step 5: migrate data
+ if ((tableExists && !tableCreate) || (!tableExists && tableCreate)) {
+ const sql = this.builderDDL(source, target, targetDatabase, targetTable, sourceRequest);
+ response = await this.getResponse(targetRequest, sql);
+ }
+ return response;
+ }
- builderDDL(source, target, targetDatabase, targetTable, sourceRequest: RequestModel): string {
- let sql
- if (source.datasource === target.datasource) {
- sql = StringUtils.format(`
+ builderDDL(source, target, targetDatabase, targetTable, sourceRequest: RequestModel): string {
+ let sql;
+ if (source.datasource === target.datasource) {
+ sql = StringUtils.format(`
INSERT INTO {0}
SELECT * FROM {1}
`, [
- StringUtils.format('`{0}`.`{1}`', [targetDatabase, targetTable]),
- StringUtils.format('`{0}`.`{1}`', [source.database, source.table])
- ])
- } else {
- const username = StringUtils.isEmpty(sourceRequest.config.username) ? '' : sourceRequest.config.username;
- const password = StringUtils.isEmpty(sourceRequest.config.password) ? '' : sourceRequest.config.password;
- sql = StringUtils.format(`
+ StringUtils.format('`{0}`.`{1}`', [targetDatabase, targetTable]),
+ StringUtils.format('`{0}`.`{1}`', [source.database, source.table])
+ ]);
+ } else {
+ const username = StringUtils.isEmpty(sourceRequest.config.username) ? '' : sourceRequest.config.username;
+ const password = StringUtils.isEmpty(sourceRequest.config.password) ? '' : sourceRequest.config.password;
+ sql = StringUtils.format(`
INSERT INTO {0}
SELECT * FROM remote('{1}', {2}, {3}, '{4}', '{5}')
`, [
- StringUtils.format('{0}.{1}', [targetDatabase, targetTable]),
- sourceRequest.config.host,
- source.database,
- source.table,
- username,
- password])
- }
- return sql
+ StringUtils.format('{0}.{1}', [targetDatabase, targetTable]),
+ sourceRequest.config.host,
+ source.database,
+ source.table,
+ username,
+ password]);
}
-
-}
\ No newline at end of file
+ return sql;
+ }
+}
diff --git a/src/renderer/services/tools/track.service.ts b/src/renderer/services/tools/track.service.ts
index 2ed0c608..3e1281d9 100644
--- a/src/renderer/services/tools/track.service.ts
+++ b/src/renderer/services/tools/track.service.ts
@@ -17,7 +17,7 @@ export class TrackService implements BaseService {
return this.httpService.post(UrlUtils.formatUrl(request), sql);
}
- getTrackInfo(aliasServerName: string, trackId: string) {
+ async getTrackInfo(aliasServerName: string, trackId: string) {
const sql = StringUtils.format(`
SELECT
query_id AS id,
@@ -45,11 +45,11 @@ ORDER BY
type DESC
`, [trackId]);
const request = new RequestModel();
- request.config = this.datasourceService.getAll(aliasServerName)?.data?.columns[0];
+ request.config = await this.datasourceService.getByAliasAsync(aliasServerName);
return this.getResponse(request, sql);
}
- getTrackTop(aliasServerName: string, top?: number) {
+ async getTrackTop(aliasServerName: string, top?: number) {
if (StringUtils.isEmpty(top)) {
top = 100;
}
@@ -65,7 +65,7 @@ LIMIT
{0}
`, [top]);
const request = new RequestModel();
- request.config = this.datasourceService.getAll(aliasServerName)?.data?.columns[0];
+ request.config = await this.datasourceService.getByAliasAsync(aliasServerName);
return this.getResponse(request, sql);
}
}