diff --git a/mayfly_go_web/src/views/personal/index.vue b/mayfly_go_web/src/views/personal/index.vue index f1b4df3a..375910c7 100644 --- a/mayfly_go_web/src/views/personal/index.vue +++ b/mayfly_go_web/src/views/personal/index.vue @@ -79,9 +79,11 @@ - + + + diff --git a/server/internal/db/api/db.go b/server/internal/db/api/db.go index 5b334a00..798e427e 100644 --- a/server/internal/db/api/db.go +++ b/server/internal/db/api/db.go @@ -128,7 +128,7 @@ func (d *Db) ExecSql(rc *ctx.ReqCtx) { dbInstance := d.DbApp.GetDbInstance(id, db) biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbInstance.Info.TagPath), "%s") - rc.ReqParam = fmt.Sprintf("%s -> %s", dbInstance.Info.GetLogDesc(), form.Sql) + rc.ReqParam = fmt.Sprintf("%s\n-> %s", dbInstance.Info.GetLogDesc(), form.Sql) biz.NotEmpty(form.Sql, "sql不能为空") // 去除前后空格及换行符 @@ -153,7 +153,9 @@ func (d *Db) ExecSql(rc *ctx.ReqCtx) { } execReq.Sql = s execRes, err := d.DbSqlExecApp.Exec(execReq) - biz.ErrIsNilAppendErr(err, "执行失败: %s") + if err != nil { + biz.ErrIsNilAppendErr(err, fmt.Sprintf("[%s] -> 执行失败: ", s)+"%s") + } if execResAll == nil { execResAll = execRes @@ -178,24 +180,33 @@ func (d *Db) ExecSqlFile(rc *ctx.ReqCtx) { filename := fileheader.Filename dbId, db := GetIdAndDb(g) - rc.ReqParam = fmt.Sprintf("dbId: %d, db: %s, filename: %s", dbId, db, filename) + dbInstance := d.DbApp.GetDbInstance(dbId, db) + biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbInstance.Info.TagPath), "%s") + rc.ReqParam = fmt.Sprintf("%s -> filename: %s", dbInstance.Info.GetLogDesc(), filename) + + logExecRecord := true + // 如果执行sql文件大于该值则不记录sql执行记录 + if fileheader.Size > 500*1024 { + logExecRecord = false + } go func() { - db := d.DbApp.GetDbInstance(dbId, db) - - dbEntity := d.DbApp.GetById(dbId) - dbInfo := fmt.Sprintf("于%s的%s环境", dbEntity.Name, dbEntity.TagPath) - defer func() { if err := recover(); err != nil { switch t := err.(type) { case *biz.BizError: - d.MsgApp.CreateAndSend(rc.LoginAccount, ws.ErrMsg("sql脚本执行失败", fmt.Sprintf("[%s]%s执行失败: [%s]", filename, dbInfo, t.Error()))) + d.MsgApp.CreateAndSend(rc.LoginAccount, ws.ErrMsg("sql脚本执行失败", fmt.Sprintf("[%s]%s执行失败: [%s]", filename, dbInstance.Info.GetLogDesc(), t.Error()))) } } }() - biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, db.Info.TagPath), "%s") + execReq := &application.DbSqlExecReq{ + DbId: dbId, + Db: db, + Remark: fileheader.Filename, + DbInstance: dbInstance, + LoginAccount: rc.LoginAccount, + } tokens := sqlparser.NewTokenizer(file) for { @@ -204,13 +215,20 @@ func (d *Db) ExecSqlFile(rc *ctx.ReqCtx) { break } sql := sqlparser.String(stmt) - _, err = db.Exec(sql) + execReq.Sql = sql + // 需要记录执行记录 + if logExecRecord { + _, err = d.DbSqlExecApp.Exec(execReq) + } else { + _, err = dbInstance.Exec(sql) + } + if err != nil { - d.MsgApp.CreateAndSend(rc.LoginAccount, ws.ErrMsg("sql脚本执行失败", fmt.Sprintf("[%s]%s执行失败: [%s]", filename, dbInfo, err.Error()))) + d.MsgApp.CreateAndSend(rc.LoginAccount, ws.ErrMsg("sql脚本执行失败", fmt.Sprintf("[%s][%s] -> sql=[%s] 执行失败: [%s]", filename, dbInstance.Info.GetLogDesc(), sql, err.Error()))) return } } - d.MsgApp.CreateAndSend(rc.LoginAccount, ws.SuccessMsg("sql脚本执行成功", fmt.Sprintf("[%s]%s执行完成", filename, dbInfo))) + d.MsgApp.CreateAndSend(rc.LoginAccount, ws.SuccessMsg("sql脚本执行成功", fmt.Sprintf("[%s]执行完成 -> %s", filename, dbInstance.Info.GetLogDesc()))) }() } @@ -258,33 +276,13 @@ func (d *Db) DumpSql(rc *ctx.ReqCtx) { writer.WriteString(fmt.Sprintf("\n-- ----------------------------\n-- 表记录: %s \n-- ----------------------------\n", table)) writer.WriteString("BEGIN;\n") - countSql := fmt.Sprintf("SELECT COUNT(*) count FROM %s", table) - _, countRes, _ := dbInstance.SelectData(countSql) - // 查询出所有列信息总数,手动分页获取所有数据 - maCount := 0 - // 查询出所有列信息总数,手动分页获取所有数据 - if count64, is64 := countRes[0]["count"].(int64); is64 { - maCount = int(count64) - } else { - maCount = countRes[0]["count"].(int) - } - // 计算需要查询的页数 - pageNum := maCount / DEFAULT_ROW_SIZE - if maCount%DEFAULT_ROW_SIZE > 0 { - pageNum++ - } - - var sqlTmp string - switch dbInstance.Info.Type { - case entity.DbTypeMysql: - sqlTmp = "SELECT * FROM %s LIMIT %d, %d" - case entity.DbTypePostgres: - sqlTmp = "SELECT * FROM %s OFFSET %d LIMIT %d" - } - for index := 0; index < pageNum; index++ { - sql := fmt.Sprintf(sqlTmp, table, index*DEFAULT_ROW_SIZE, DEFAULT_ROW_SIZE) - columns, result, _ := dbInstance.SelectData(sql) - + pageNum := 1 + for { + columns, result, _ := dbmeta.GetTableRecord(table, pageNum, DEFAULT_ROW_SIZE) + resultLen := len(result) + if resultLen == 0 { + break + } insertSql := "INSERT INTO `%s` VALUES (%s);\n" for _, res := range result { var values []string @@ -303,19 +301,22 @@ func (d *Db) DumpSql(rc *ctx.ReqCtx) { } writer.WriteString(fmt.Sprintf(insertSql, table, strings.Join(values, ", "))) } + if resultLen < DEFAULT_ROW_SIZE { + break + } + pageNum++ } writer.WriteString("COMMIT;\n") } rc.NoRes = true - rc.ReqParam = fmt.Sprintf("dbId: %d, db: %s, tables: %s, dumpType: %s", dbId, db, tablesStr, dumpType) + rc.ReqParam = fmt.Sprintf("%s, tables: %s, dumpType: %s", dbInstance.Info.GetLogDesc(), tablesStr, dumpType) } // @router /api/db/:dbId/t-metadata [get] func (d *Db) TableMA(rc *ctx.ReqCtx) { dbi := d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx)) - biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbi.Info.TagPath), "%s") rc.ResData = dbi.GetMeta().GetTables() } @@ -326,14 +327,12 @@ func (d *Db) ColumnMA(rc *ctx.ReqCtx) { biz.NotEmpty(tn, "tableName不能为空") dbi := d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx)) - // biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbInstance.TagPath), "%s") rc.ResData = dbi.GetMeta().GetColumns(tn) } // @router /api/db/:dbId/hint-tables [get] func (d *Db) HintTables(rc *ctx.ReqCtx) { dbi := d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx)) - // biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbInstance.TagPath), "%s") dm := dbi.GetMeta() // 获取所有表 diff --git a/server/internal/db/application/db_sql_exec.go b/server/internal/db/application/db_sql_exec.go index 70e25ced..d2e2fccf 100644 --- a/server/internal/db/application/db_sql_exec.go +++ b/server/internal/db/application/db_sql_exec.go @@ -220,5 +220,5 @@ func doExec(sql string, dbInstance *DbInstance) (*DbSqlExecRes, error) { return &DbSqlExecRes{ ColNames: []string{"sql", "rowsAffected", "result"}, Res: res, - }, nil + }, err } diff --git a/server/internal/db/application/meta.go b/server/internal/db/application/meta.go index 2459e612..31fb6d10 100644 --- a/server/internal/db/application/meta.go +++ b/server/internal/db/application/meta.go @@ -1,7 +1,7 @@ package application // -----------------------------------元数据接口定义------------------------------------------ -// 数据库元信息接口(表、列等元信息) +// 数据库元信息接口(表、列、获取表数据等元信息) // 所有数据查出来直接用map接收,注意不同数据库实现该接口返回的map中的key需要统一. // 即: 使用别名统一即可。如table_name AS tableName type DbMetadata interface { @@ -25,4 +25,8 @@ type DbMetadata interface { // 获取建表ddl GetCreateTableDdl(tableName string) []map[string]interface{} + + // 获取指定表的数据-分页查询 + // @return columns: 列字段名;result: 结果集;error: 错误 + GetTableRecord(tableName string, pageNum, pageSize int) ([]string, []map[string]interface{}, error) } diff --git a/server/internal/db/application/mysql_meta.go b/server/internal/db/application/mysql_meta.go index e45e5203..a1a1cde3 100644 --- a/server/internal/db/application/mysql_meta.go +++ b/server/internal/db/application/mysql_meta.go @@ -103,3 +103,7 @@ func (mm *MysqlMetadata) GetCreateTableDdl(tableName string) []map[string]interf res, _ := mm.di.innerSelect(fmt.Sprintf("show create table %s ", tableName)) return res } + +func (mm *MysqlMetadata) GetTableRecord(tableName string, pageNum, pageSize int) ([]string, []map[string]interface{}, error) { + return mm.di.SelectData(fmt.Sprintf("SELECT * FROM %s LIMIT %d, %d", tableName, (pageNum-1)*pageSize, pageSize)) +} diff --git a/server/internal/db/application/pgsql_meta.go b/server/internal/db/application/pgsql_meta.go index 1e1ba2bc..c9a0ab4f 100644 --- a/server/internal/db/application/pgsql_meta.go +++ b/server/internal/db/application/pgsql_meta.go @@ -95,7 +95,11 @@ func (pm *PgsqlMetadata) GetTableIndex(tableName string) []map[string]interface{ } // 获取建表ddl -func (mm *PgsqlMetadata) GetCreateTableDdl(tableName string) []map[string]interface{} { +func (pm *PgsqlMetadata) GetCreateTableDdl(tableName string) []map[string]interface{} { biz.IsTrue(tableName == "", "暂不支持获取pgsql建表DDL") return nil } + +func (pm *PgsqlMetadata) GetTableRecord(tableName string, pageNum, pageSize int) ([]string, []map[string]interface{}, error) { + return pm.di.SelectData(fmt.Sprintf("SELECT * FROM %s OFFSET %d LIMIT %d", tableName, (pageNum-1)*pageSize, pageSize)) +}