From 1db990b5549742a99760a9dc500ac08c6e4176bf Mon Sep 17 00:00:00 2001
From: "meilin.huang" <954537473@qq.com>
Date: Thu, 7 Dec 2023 11:48:17 +0800
Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=96=B0=E5=A2=9E=E8=BE=BE?=
=?UTF-8?q?=E6=A2=A6=E5=9B=BE=E6=A0=87=E3=80=81=E8=B0=83=E6=95=B4=E5=89=8D?=
=?UTF-8?q?=E7=AB=AFDbDialect=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
mayfly_go_web/src/assets/iconfont/iconfont.js | 2 +-
.../src/assets/iconfont/iconfont.json | 7 ++++
.../src/views/ops/db/InstanceEdit.vue | 38 +++++++++++++++----
mayfly_go_web/src/views/ops/db/SqlExec.vue | 6 +--
.../ops/db/component/table/DbTableDataOp.vue | 2 +-
.../ops/db/component/table/DbTableOp.vue | 4 +-
.../src/views/ops/db/dialect/dm_dialect.ts | 22 +++++------
.../src/views/ops/db/dialect/index.ts | 37 ++++++++++++------
.../src/views/ops/db/dialect/mysql_dialect.ts | 22 +++++------
.../views/ops/db/dialect/postgres_dialect.ts | 22 +++++------
server/go.mod | 3 +-
server/internal/db/api/db.go | 2 +-
server/internal/db/dbm/conn.go | 21 ++++++----
server/internal/db/dbm/dialect_dm.go | 3 +-
14 files changed, 117 insertions(+), 74 deletions(-)
diff --git a/mayfly_go_web/src/assets/iconfont/iconfont.js b/mayfly_go_web/src/assets/iconfont/iconfont.js
index b9b4f4d5..7e31d647 100644
--- a/mayfly_go_web/src/assets/iconfont/iconfont.js
+++ b/mayfly_go_web/src/assets/iconfont/iconfont.js
@@ -1,5 +1,5 @@
(window._iconfont_svg_string_3953964 =
- ''),
+ ''),
(function (c) {
var t = (t = document.getElementsByTagName('script'))[t.length - 1],
a = t.getAttribute('data-injectcss'),
diff --git a/mayfly_go_web/src/assets/iconfont/iconfont.json b/mayfly_go_web/src/assets/iconfont/iconfont.json
index baab9418..9cdae18d 100644
--- a/mayfly_go_web/src/assets/iconfont/iconfont.json
+++ b/mayfly_go_web/src/assets/iconfont/iconfont.json
@@ -26,6 +26,13 @@
"unicode": "e8b7",
"unicode_decimal": 59575
},
+ {
+ "icon_id": "12295203",
+ "name": "达梦数据库",
+ "font_class": "db-dm",
+ "unicode": "e6f0",
+ "unicode_decimal": 59120
+ },
{
"icon_id": "10055634",
"name": "云数据库MongoDB",
diff --git a/mayfly_go_web/src/views/ops/db/InstanceEdit.vue b/mayfly_go_web/src/views/ops/db/InstanceEdit.vue
index 2ca210e9..d182fdd5 100644
--- a/mayfly_go_web/src/views/ops/db/InstanceEdit.vue
+++ b/mayfly_go_web/src/views/ops/db/InstanceEdit.vue
@@ -8,10 +8,11 @@
-
-
-
-
+
+
+
+ {{ dt.label }}
+
@@ -86,6 +87,8 @@ import { ElMessage } from 'element-plus';
import { notBlank } from '@/common/assert';
import { RsaEncrypt } from '@/common/rsa';
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
+import { getDbDialect } from './dialect';
+import SvgIcon from '@/components/svgIcon/index.vue';
const props = defineProps({
visible: {
@@ -121,7 +124,7 @@ const rules = {
{
required: true,
message: '请输入主机ip和port',
- trigger: ['change', 'blur'],
+ trigger: ['blur'],
},
],
username: [
@@ -135,6 +138,21 @@ const rules = {
const dbForm: any = ref(null);
+const dbTypes = [
+ {
+ type: 'mysql',
+ label: 'mysql',
+ },
+ {
+ type: 'postgres',
+ label: 'postgres',
+ },
+ {
+ type: 'dm',
+ label: '达梦(暂不支持ssh)',
+ },
+];
+
const state = reactive({
dialogVisible: false,
tabActiveName: 'basic',
@@ -143,7 +161,7 @@ const state = reactive({
type: null,
name: null,
host: '',
- port: 3306,
+ port: null,
username: null,
password: null,
params: null,
@@ -170,11 +188,17 @@ watch(props, (newValue: any) => {
state.form = { ...newValue.data };
state.oldUserName = state.form.username;
} else {
- state.form = { port: 3306 } as any;
+ state.form = { port: null } as any;
state.oldUserName = null;
}
});
+const changeDbType = (val: string) => {
+ if (!state.form.id) {
+ state.form.port = getDbDialect(val).getInfo().defaultPort as any;
+ }
+};
+
const getDbPwd = async () => {
state.pwd = await dbApi.getInstancePwd.request({ id: state.form.id });
};
diff --git a/mayfly_go_web/src/views/ops/db/SqlExec.vue b/mayfly_go_web/src/views/ops/db/SqlExec.vue
index 405cea22..3b738699 100644
--- a/mayfly_go_web/src/views/ops/db/SqlExec.vue
+++ b/mayfly_go_web/src/views/ops/db/SqlExec.vue
@@ -7,7 +7,7 @@
-
+
@@ -66,7 +66,7 @@
-
+
实例
@@ -104,7 +104,7 @@
{{ dt.params.name }}
-
+
{{ dt.params.host }}
diff --git a/mayfly_go_web/src/views/ops/db/component/table/DbTableDataOp.vue b/mayfly_go_web/src/views/ops/db/component/table/DbTableDataOp.vue
index 5b76189e..c4c0403f 100644
--- a/mayfly_go_web/src/views/ops/db/component/table/DbTableDataOp.vue
+++ b/mayfly_go_web/src/views/ops/db/component/table/DbTableDataOp.vue
@@ -332,7 +332,7 @@ const selectData = async () => {
const table = props.tableName;
try {
const countRes = await dbInst.runSql(db, dbInst.getDefaultCountSql(table, state.condition));
- state.count = countRes.res[0].count || countRes.res[0].COUNT;
+ state.count = countRes.res[0].count || countRes.res[0].COUNT || 0;
let sql = dbInst.getDefaultSelectSql(table, state.condition, state.orderBy, state.pageNum, state.pageSize);
state.sql = sql;
if (state.count > 0) {
diff --git a/mayfly_go_web/src/views/ops/db/component/table/DbTableOp.vue b/mayfly_go_web/src/views/ops/db/component/table/DbTableOp.vue
index 799ce35a..617fc4ca 100644
--- a/mayfly_go_web/src/views/ops/db/component/table/DbTableOp.vue
+++ b/mayfly_go_web/src/views/ops/db/component/table/DbTableOp.vue
@@ -167,7 +167,7 @@ const state = reactive({
dialogVisible: false,
btnloading: false,
activeName: '1',
- columnTypeList: dbDialect.getColumnTypes(),
+ columnTypeList: dbDialect.getInfo().columnTypes,
indexTypeList: ['BTREE'], // mysql索引类型详解 http://c.biancheng.net/view/7897.html
tableData: {
fields: {
@@ -425,7 +425,7 @@ const submit = async () => {
sql: sql,
dbId: props.dbId as any,
db: props.db as any,
- dbType: dbDialect.getFormatDialect(),
+ dbType: dbDialect.getInfo().formatSqlDialect,
runSuccessCallback: () => {
emit('submit-sql', { tableName: state.tableData.tableName });
// cancel();
diff --git a/mayfly_go_web/src/views/ops/db/dialect/dm_dialect.ts b/mayfly_go_web/src/views/ops/db/dialect/dm_dialect.ts
index 62c829cb..c318f0b6 100644
--- a/mayfly_go_web/src/views/ops/db/dialect/dm_dialect.ts
+++ b/mayfly_go_web/src/views/ops/db/dialect/dm_dialect.ts
@@ -1,5 +1,4 @@
-import { DbDialect, sqlColumnType } from './index';
-import { SqlLanguage } from 'sql-formatter/lib/src/sqlFormatter';
+import { DbDialect, sqlColumnType, DialectInfo } from './index';
export { DMDialect, GAUSS_TYPE_LIST };
@@ -83,13 +82,16 @@ const GAUSS_TYPE_LIST: sqlColumnType[] = [
{ udtName: 'macaddr', dataType: 'macaddr', desc: 'MAC地址', space: '6字节' },
];
-class DMDialect implements DbDialect {
- getFormatDialect(): SqlLanguage {
- return 'postgresql';
- }
+const dmDialectInfo: DialectInfo = {
+ icon: 'iconfont icon-db-dm',
+ defaultPort: 5236,
+ formatSqlDialect: 'postgresql',
+ columnTypes: GAUSS_TYPE_LIST.sort((a, b) => a.udtName.localeCompare(b.udtName)),
+};
- getIcon() {
- return 'iconfont icon-op-postgres';
+class DMDialect implements DbDialect {
+ getInfo() {
+ return dmDialectInfo;
}
getDefaultSelectSql(table: string, condition: string, orderBy: string, pageNum: number, limit: number) {
@@ -102,10 +104,6 @@ class DMDialect implements DbDialect {
return name;
};
- getColumnTypes(): sqlColumnType[] {
- return GAUSS_TYPE_LIST.sort((a, b) => a.udtName.localeCompare(b.udtName));
- }
-
matchType(text: string, arr: string[]): boolean {
if (!text || !arr || arr.length === 0) {
return false;
diff --git a/mayfly_go_web/src/views/ops/db/dialect/index.ts b/mayfly_go_web/src/views/ops/db/dialect/index.ts
index 135cb61e..d6d9b063 100644
--- a/mayfly_go_web/src/views/ops/db/dialect/index.ts
+++ b/mayfly_go_web/src/views/ops/db/dialect/index.ts
@@ -11,6 +11,29 @@ export interface sqlColumnType {
range?: string;
}
+// 数据库基础信息
+export interface DialectInfo {
+ /**
+ * 图标
+ */
+ icon: string;
+
+ /**
+ * 默认端口
+ */
+ defaultPort: number;
+
+ /**
+ * 格式化sql的方言
+ */
+ formatSqlDialect: SqlLanguage;
+
+ /**
+ * 列字段类型
+ */
+ columnTypes: sqlColumnType[];
+}
+
export const DbType = {
mysql: 'mysql',
postgresql: 'postgres',
@@ -19,14 +42,9 @@ export const DbType = {
export interface DbDialect {
/**
- * 获取格式化sql对应的dialect名称
+ * 获取一些数据库默认信息
*/
- getFormatDialect(): SqlLanguage;
-
- /**
- * 获取图标信息
- */
- getIcon(): string;
+ getInfo(): DialectInfo;
/**
* 获取默认查询sql
@@ -44,11 +62,6 @@ export interface DbDialect {
*/
wrapName(name: string): string;
- /**
- * 生成字段类型列表
- * */
- getColumnTypes(): sqlColumnType[];
-
/**
* 生成创建表sql
* @param tableData 建表数据
diff --git a/mayfly_go_web/src/views/ops/db/dialect/mysql_dialect.ts b/mayfly_go_web/src/views/ops/db/dialect/mysql_dialect.ts
index ac9a100d..05cbe795 100644
--- a/mayfly_go_web/src/views/ops/db/dialect/mysql_dialect.ts
+++ b/mayfly_go_web/src/views/ops/db/dialect/mysql_dialect.ts
@@ -1,5 +1,4 @@
-import { DbDialect, sqlColumnType } from './index';
-import { SqlLanguage } from 'sql-formatter/lib/src/sqlFormatter';
+import { DbDialect, DialectInfo } from './index';
export { MYSQL_TYPE_LIST, MysqlDialect, language };
@@ -30,13 +29,16 @@ const MYSQL_TYPE_LIST = [
'varchar',
];
-class MysqlDialect implements DbDialect {
- getFormatDialect(): SqlLanguage {
- return 'mysql';
- }
+const mysqlDialectInfo: DialectInfo = {
+ icon: 'iconfont icon-op-mysql',
+ defaultPort: 3306,
+ formatSqlDialect: 'mysql',
+ columnTypes: MYSQL_TYPE_LIST.map((a) => ({ udtName: a, dataType: a, desc: '', space: '' })),
+};
- getIcon() {
- return 'iconfont icon-op-mysql';
+class MysqlDialect implements DbDialect {
+ getInfo(): DialectInfo {
+ return mysqlDialectInfo;
}
getDefaultSelectSql(table: string, condition: string, orderBy: string, pageNum: number, limit: number) {
@@ -49,10 +51,6 @@ class MysqlDialect implements DbDialect {
return `\`${name}\``;
};
- getColumnTypes(): sqlColumnType[] {
- return MYSQL_TYPE_LIST.map((a) => ({ udtName: a, dataType: a, desc: '', space: '' }));
- }
-
genColumnBasicSql(cl: any): string {
let val = cl.value ? (cl.value === 'CURRENT_TIMESTAMP' ? cl.value : `'${cl.value}'`) : '';
let defVal = val ? `DEFAULT ${val}` : '';
diff --git a/mayfly_go_web/src/views/ops/db/dialect/postgres_dialect.ts b/mayfly_go_web/src/views/ops/db/dialect/postgres_dialect.ts
index 7a8b8adc..6ee1ad88 100644
--- a/mayfly_go_web/src/views/ops/db/dialect/postgres_dialect.ts
+++ b/mayfly_go_web/src/views/ops/db/dialect/postgres_dialect.ts
@@ -1,5 +1,4 @@
-import { DbDialect, sqlColumnType } from './index';
-import { SqlLanguage } from 'sql-formatter/lib/src/sqlFormatter';
+import { DbDialect, DialectInfo, sqlColumnType } from './index';
export { PostgresqlDialect, GAUSS_TYPE_LIST };
@@ -83,13 +82,16 @@ const GAUSS_TYPE_LIST: sqlColumnType[] = [
{ udtName: 'macaddr', dataType: 'macaddr', desc: 'MAC地址', space: '6字节' },
];
-class PostgresqlDialect implements DbDialect {
- getFormatDialect(): SqlLanguage {
- return 'postgresql';
- }
+const postgresDialectInfo: DialectInfo = {
+ icon: 'iconfont icon-op-postgres',
+ defaultPort: 5432,
+ formatSqlDialect: 'postgresql',
+ columnTypes: GAUSS_TYPE_LIST.sort((a, b) => a.udtName.localeCompare(b.udtName)),
+};
- getIcon() {
- return 'iconfont icon-op-postgres';
+class PostgresqlDialect implements DbDialect {
+ getInfo(): DialectInfo {
+ return postgresDialectInfo;
}
getDefaultSelectSql(table: string, condition: string, orderBy: string, pageNum: number, limit: number) {
@@ -102,10 +104,6 @@ class PostgresqlDialect implements DbDialect {
return name;
};
- getColumnTypes(): sqlColumnType[] {
- return GAUSS_TYPE_LIST.sort((a, b) => a.udtName.localeCompare(b.udtName));
- }
-
matchType(text: string, arr: string[]): boolean {
if (!text || !arr || arr.length === 0) {
return false;
diff --git a/server/go.mod b/server/go.mod
index f09e83ec..e1b5684c 100644
--- a/server/go.mod
+++ b/server/go.mod
@@ -34,8 +34,6 @@ require (
gorm.io/gorm v1.25.5
)
-require golang.org/x/exp v0.0.0-20230519143937-03e91628a987
-
require (
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
@@ -79,6 +77,7 @@ require (
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
golang.org/x/arch v0.3.0 // indirect
+ golang.org/x/exp v0.0.0-20230519143937-03e91628a987
golang.org/x/image v0.0.0-20220302094943-723b81ca9867 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/sync v0.1.0 // indirect
diff --git a/server/internal/db/api/db.go b/server/internal/db/api/db.go
index 353eb352..687e14b2 100644
--- a/server/internal/db/api/db.go
+++ b/server/internal/db/api/db.go
@@ -115,7 +115,7 @@ func (d *Db) ExecSql(rc *req.Ctx) {
ctx := rc.MetaCtx
// 如果存在执行id,则保存取消函数,用于后续可能的取消操作
if form.ExecId != "" {
- cancelCtx, cancel := context.WithCancel(rc.MetaCtx)
+ cancelCtx, cancel := context.WithTimeout(rc.MetaCtx, 55*time.Second)
ctx = cancelCtx
cancelExecSqlMap.Store(form.ExecId, cancel)
defer cancelExecSqlMap.Delete(form.ExecId)
diff --git a/server/internal/db/dbm/conn.go b/server/internal/db/dbm/conn.go
index 05e728da..c601f9bb 100644
--- a/server/internal/db/dbm/conn.go
+++ b/server/internal/db/dbm/conn.go
@@ -33,10 +33,7 @@ func (d *DbConn) QueryContext(ctx context.Context, querySql string) ([]string, [
result = append(result, record)
})
if err != nil {
- if err == context.Canceled {
- return nil, nil, errorx.NewBiz("取消执行")
- }
- return nil, nil, err
+ return nil, nil, wrapSqlError(err)
}
return columns, result, nil
}
@@ -74,10 +71,7 @@ func (d *DbConn) Exec(sql string) (int64, error) {
func (d *DbConn) ExecContext(ctx context.Context, sql string) (int64, error) {
res, err := d.db.ExecContext(ctx, sql)
if err != nil {
- if err == context.Canceled {
- return 0, errorx.NewBiz("取消执行")
- }
- return 0, err
+ return 0, wrapSqlError(err)
}
return res.RowsAffected()
}
@@ -202,3 +196,14 @@ func valueConvert(data []byte, colType *sql.ColumnType) any {
return stringV
}
+
+// 包装sql执行相关错误
+func wrapSqlError(err error) error {
+ if err == context.Canceled {
+ return errorx.NewBiz("取消执行")
+ }
+ if err == context.DeadlineExceeded {
+ return errorx.NewBiz("执行超时")
+ }
+ return err
+}
diff --git a/server/internal/db/dbm/dialect_dm.go b/server/internal/db/dbm/dialect_dm.go
index 029d694a..f65d6614 100644
--- a/server/internal/db/dbm/dialect_dm.go
+++ b/server/internal/db/dbm/dialect_dm.go
@@ -4,10 +4,11 @@ import (
"context"
"database/sql"
"fmt"
- _ "gitee.com/chunanyong/dm"
"mayfly-go/pkg/errorx"
"mayfly-go/pkg/utils/anyx"
"strings"
+
+ _ "gitee.com/chunanyong/dm"
)
func getDmDB(d *DbInfo) (*sql.DB, error) {