2022-06-16 15:55:18 +08:00
|
|
|
|
package application
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2023-11-07 21:05:21 +08:00
|
|
|
|
"context"
|
2022-06-16 15:55:18 +08:00
|
|
|
|
"fmt"
|
2023-08-31 21:49:20 +08:00
|
|
|
|
"mayfly-go/internal/db/config"
|
2024-01-12 13:15:30 +08:00
|
|
|
|
"mayfly-go/internal/db/dbm/dbi"
|
2022-09-09 18:26:08 +08:00
|
|
|
|
"mayfly-go/internal/db/domain/entity"
|
|
|
|
|
|
"mayfly-go/internal/db/domain/repository"
|
2024-02-29 22:12:50 +08:00
|
|
|
|
flowapp "mayfly-go/internal/flow/application"
|
|
|
|
|
|
flowentity "mayfly-go/internal/flow/domain/entity"
|
2023-12-07 01:07:34 +08:00
|
|
|
|
"mayfly-go/pkg/contextx"
|
2023-10-26 17:15:49 +08:00
|
|
|
|
"mayfly-go/pkg/errorx"
|
2024-01-29 04:20:23 +00:00
|
|
|
|
"mayfly-go/pkg/logx"
|
2022-06-16 15:55:18 +08:00
|
|
|
|
"mayfly-go/pkg/model"
|
2024-01-09 21:37:56 +08:00
|
|
|
|
"mayfly-go/pkg/utils/jsonx"
|
2024-02-29 22:12:50 +08:00
|
|
|
|
"mayfly-go/pkg/utils/stringx"
|
2023-02-13 21:11:16 +08:00
|
|
|
|
"strconv"
|
2022-06-16 15:55:18 +08:00
|
|
|
|
"strings"
|
2023-10-12 12:14:56 +08:00
|
|
|
|
|
|
|
|
|
|
"github.com/kanzihuang/vitess/go/vt/sqlparser"
|
2022-06-16 15:55:18 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2022-09-22 11:56:21 +08:00
|
|
|
|
type DbSqlExecReq struct {
|
2023-12-07 01:07:34 +08:00
|
|
|
|
DbId uint64
|
|
|
|
|
|
Db string
|
|
|
|
|
|
Sql string
|
|
|
|
|
|
Remark string
|
2024-01-12 13:15:30 +08:00
|
|
|
|
DbConn *dbi.DbConn
|
2022-09-22 11:56:21 +08:00
|
|
|
|
}
|
2022-09-09 18:26:08 +08:00
|
|
|
|
|
2022-09-22 11:56:21 +08:00
|
|
|
|
type DbSqlExecRes struct {
|
2024-01-12 13:15:30 +08:00
|
|
|
|
Columns []*dbi.QueryColumn
|
2023-12-14 21:27:11 +08:00
|
|
|
|
Res []map[string]any
|
2022-09-22 11:56:21 +08:00
|
|
|
|
}
|
2022-06-16 15:55:18 +08:00
|
|
|
|
|
2022-11-02 19:27:40 +08:00
|
|
|
|
// 合并执行结果,主要用于执行多条sql使用
|
|
|
|
|
|
func (d *DbSqlExecRes) Merge(execRes *DbSqlExecRes) {
|
2023-12-14 21:27:11 +08:00
|
|
|
|
canMerge := len(d.Columns) == len(execRes.Columns)
|
2022-11-02 19:27:40 +08:00
|
|
|
|
if !canMerge {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
// 列名不一致,则不合并
|
2023-12-14 21:27:11 +08:00
|
|
|
|
for i, col := range d.Columns {
|
|
|
|
|
|
if execRes.Columns[i].Name != col.Name {
|
2022-11-02 19:27:40 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
d.Res = append(d.Res, execRes.Res...)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-22 11:56:21 +08:00
|
|
|
|
type DbSqlExec interface {
|
2024-02-29 22:12:50 +08:00
|
|
|
|
flowapp.FlowBizHandler
|
|
|
|
|
|
|
2022-09-22 11:56:21 +08:00
|
|
|
|
// 执行sql
|
2023-12-07 01:07:34 +08:00
|
|
|
|
Exec(ctx context.Context, execSqlReq *DbSqlExecReq) (*DbSqlExecRes, error)
|
2022-06-16 15:55:18 +08:00
|
|
|
|
|
|
|
|
|
|
// 根据条件删除sql执行记录
|
2024-05-05 14:53:30 +08:00
|
|
|
|
DeleteBy(ctx context.Context, condition *entity.DbSqlExec) error
|
2022-06-16 15:55:18 +08:00
|
|
|
|
|
|
|
|
|
|
// 分页获取
|
2023-10-26 17:15:49 +08:00
|
|
|
|
GetPageList(condition *entity.DbSqlExecQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
|
2022-06-16 15:55:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-09 18:26:08 +08:00
|
|
|
|
type dbSqlExecAppImpl struct {
|
2024-02-29 22:12:50 +08:00
|
|
|
|
dbApp Db `inject:"DbApp"`
|
2024-01-23 19:30:28 +08:00
|
|
|
|
dbSqlExecRepo repository.DbSqlExec `inject:"DbSqlExecRepo"`
|
2024-02-29 22:12:50 +08:00
|
|
|
|
|
|
|
|
|
|
flowProcinstApp flowapp.Procinst `inject:"ProcinstApp"`
|
2024-05-08 21:04:25 +08:00
|
|
|
|
flowProcdefApp flowapp.Procdef `inject:"ProcdefApp"`
|
2022-06-16 15:55:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-07 01:07:34 +08:00
|
|
|
|
func createSqlExecRecord(ctx context.Context, execSqlReq *DbSqlExecReq) *entity.DbSqlExec {
|
2022-11-01 12:45:21 +08:00
|
|
|
|
dbSqlExecRecord := new(entity.DbSqlExec)
|
|
|
|
|
|
dbSqlExecRecord.DbId = execSqlReq.DbId
|
|
|
|
|
|
dbSqlExecRecord.Db = execSqlReq.Db
|
|
|
|
|
|
dbSqlExecRecord.Sql = execSqlReq.Sql
|
|
|
|
|
|
dbSqlExecRecord.Remark = execSqlReq.Remark
|
2024-02-29 22:12:50 +08:00
|
|
|
|
dbSqlExecRecord.Status = entity.DbSqlExecStatusSuccess
|
2024-01-09 17:31:21 +08:00
|
|
|
|
dbSqlExecRecord.FillBaseInfo(model.IdGenTypeNone, contextx.GetLoginAccount(ctx))
|
2022-11-01 12:45:21 +08:00
|
|
|
|
return dbSqlExecRecord
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-07 01:07:34 +08:00
|
|
|
|
func (d *dbSqlExecAppImpl) Exec(ctx context.Context, execSqlReq *DbSqlExecReq) (*DbSqlExecRes, error) {
|
2022-09-22 11:56:21 +08:00
|
|
|
|
sql := execSqlReq.Sql
|
2023-12-07 01:07:34 +08:00
|
|
|
|
dbSqlExecRecord := createSqlExecRecord(ctx, execSqlReq)
|
2023-07-05 22:06:32 +08:00
|
|
|
|
dbSqlExecRecord.Type = entity.DbSqlExecTypeOther
|
2023-02-13 21:11:16 +08:00
|
|
|
|
var execRes *DbSqlExecRes
|
|
|
|
|
|
isSelect := false
|
|
|
|
|
|
|
2022-06-16 15:55:18 +08:00
|
|
|
|
stmt, err := sqlparser.Parse(sql)
|
|
|
|
|
|
if err != nil {
|
2023-02-13 21:11:16 +08:00
|
|
|
|
// 就算解析失败也执行sql,让数据库来判断错误。如果是查询sql则简单判断是否有limit分页参数信息(兼容pgsql)
|
2023-09-02 17:24:18 +08:00
|
|
|
|
// logx.Warnf("sqlparse解析sql[%s]失败: %s", sql, err.Error())
|
2023-02-13 21:11:16 +08:00
|
|
|
|
lowerSql := strings.ToLower(execSqlReq.Sql)
|
2024-04-13 17:01:12 +08:00
|
|
|
|
isSelect := strings.HasPrefix(lowerSql, "select") || strings.HasPrefix(lowerSql, "explain")
|
2023-02-13 21:11:16 +08:00
|
|
|
|
if isSelect {
|
2023-03-15 11:41:03 +08:00
|
|
|
|
// 如果配置为0,则不校验分页参数
|
2024-03-07 17:26:11 +08:00
|
|
|
|
maxCount := config.GetDbms().MaxResultSet
|
2023-03-15 11:41:03 +08:00
|
|
|
|
if maxCount != 0 {
|
2024-01-29 04:20:23 +00:00
|
|
|
|
if !strings.Contains(lowerSql, "limit") &&
|
|
|
|
|
|
// 兼容oracle rownum分页
|
|
|
|
|
|
!strings.Contains(lowerSql, "rownum") &&
|
|
|
|
|
|
// 兼容mssql offset分页
|
|
|
|
|
|
!strings.Contains(lowerSql, "offset") &&
|
|
|
|
|
|
// 兼容mssql top 分页 with result as ({query sql}) select top 100 * from result
|
|
|
|
|
|
!strings.Contains(lowerSql, " top ") {
|
2024-01-19 08:59:35 +00:00
|
|
|
|
// 判断是不是count语句
|
|
|
|
|
|
if !strings.Contains(lowerSql, "count(") {
|
|
|
|
|
|
return nil, errorx.NewBiz("请完善分页信息后执行")
|
|
|
|
|
|
}
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
2023-03-15 11:41:03 +08:00
|
|
|
|
}
|
2023-02-13 21:11:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
var execErr error
|
|
|
|
|
|
if isSelect || strings.HasPrefix(lowerSql, "show") {
|
2024-02-29 22:12:50 +08:00
|
|
|
|
execRes, execErr = d.doRead(ctx, execSqlReq)
|
2023-02-13 21:11:16 +08:00
|
|
|
|
} else {
|
2024-02-29 22:12:50 +08:00
|
|
|
|
execRes, execErr = d.doExec(ctx, execSqlReq, dbSqlExecRecord)
|
2022-11-01 12:45:21 +08:00
|
|
|
|
}
|
2024-03-02 19:08:19 +08:00
|
|
|
|
|
|
|
|
|
|
d.saveSqlExecLog(isSelect, dbSqlExecRecord)
|
2023-02-13 21:11:16 +08:00
|
|
|
|
if execErr != nil {
|
|
|
|
|
|
return nil, execErr
|
|
|
|
|
|
}
|
|
|
|
|
|
return execRes, nil
|
2022-06-16 15:55:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch stmt := stmt.(type) {
|
2022-09-22 11:56:21 +08:00
|
|
|
|
case *sqlparser.Select:
|
|
|
|
|
|
isSelect = true
|
2024-02-29 22:12:50 +08:00
|
|
|
|
execRes, err = d.doSelect(ctx, stmt, execSqlReq)
|
2024-04-13 17:01:12 +08:00
|
|
|
|
case *sqlparser.ExplainStmt:
|
|
|
|
|
|
isSelect = true
|
|
|
|
|
|
execRes, err = d.doRead(ctx, execSqlReq)
|
2022-09-22 11:56:21 +08:00
|
|
|
|
case *sqlparser.Show:
|
|
|
|
|
|
isSelect = true
|
2024-02-29 22:12:50 +08:00
|
|
|
|
execRes, err = d.doRead(ctx, execSqlReq)
|
2022-09-22 11:56:21 +08:00
|
|
|
|
case *sqlparser.OtherRead:
|
|
|
|
|
|
isSelect = true
|
2024-02-29 22:12:50 +08:00
|
|
|
|
execRes, err = d.doRead(ctx, execSqlReq)
|
2022-06-16 15:55:18 +08:00
|
|
|
|
case *sqlparser.Update:
|
2024-02-29 22:12:50 +08:00
|
|
|
|
execRes, err = d.doUpdate(ctx, stmt, execSqlReq, dbSqlExecRecord)
|
2022-06-16 15:55:18 +08:00
|
|
|
|
case *sqlparser.Delete:
|
2024-02-29 22:12:50 +08:00
|
|
|
|
execRes, err = d.doDelete(ctx, stmt, execSqlReq, dbSqlExecRecord)
|
2022-06-16 15:55:18 +08:00
|
|
|
|
case *sqlparser.Insert:
|
2024-02-29 22:12:50 +08:00
|
|
|
|
execRes, err = d.doInsert(ctx, stmt, execSqlReq, dbSqlExecRecord)
|
2022-09-22 11:56:21 +08:00
|
|
|
|
default:
|
2024-02-29 22:12:50 +08:00
|
|
|
|
execRes, err = d.doExec(ctx, execSqlReq, dbSqlExecRecord)
|
2022-09-22 11:56:21 +08:00
|
|
|
|
}
|
2024-02-29 22:12:50 +08:00
|
|
|
|
|
|
|
|
|
|
d.saveSqlExecLog(isSelect, dbSqlExecRecord)
|
2022-09-22 11:56:21 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
2022-06-16 15:55:18 +08:00
|
|
|
|
}
|
2023-02-13 21:11:16 +08:00
|
|
|
|
return execRes, nil
|
|
|
|
|
|
}
|
2022-06-16 15:55:18 +08:00
|
|
|
|
|
2024-03-02 19:08:19 +08:00
|
|
|
|
func (d *dbSqlExecAppImpl) FlowBizHandle(ctx context.Context, bizHandleParam *flowapp.BizHandleParam) error {
|
|
|
|
|
|
bizKey := bizHandleParam.BizKey
|
|
|
|
|
|
procinstStatus := bizHandleParam.ProcinstStatus
|
|
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
logx.Debugf("DbSqlExec FlowBizHandle -> bizKey: %s, procinstStatus: %s", bizKey, flowentity.ProcinstStatusEnum.GetDesc(procinstStatus))
|
|
|
|
|
|
// 流程挂起不处理
|
2024-03-02 19:08:19 +08:00
|
|
|
|
if procinstStatus == flowentity.ProcinstStatusSuspended {
|
2024-02-29 22:12:50 +08:00
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
dbSqlExec := &entity.DbSqlExec{FlowBizKey: bizKey}
|
2024-04-28 23:45:57 +08:00
|
|
|
|
if err := d.dbSqlExecRepo.GetByCond(dbSqlExec); err != nil {
|
2024-02-29 22:12:50 +08:00
|
|
|
|
logx.Errorf("flow-[%s]关联的sql执行信息不存在", bizKey)
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-03-02 19:08:19 +08:00
|
|
|
|
if procinstStatus != flowentity.ProcinstStatusCompleted {
|
2024-02-29 22:12:50 +08:00
|
|
|
|
dbSqlExec.Status = entity.DbSqlExecStatusNo
|
|
|
|
|
|
dbSqlExec.Res = fmt.Sprintf("流程%s", flowentity.ProcinstStatusEnum.GetDesc(procinstStatus))
|
|
|
|
|
|
return d.dbSqlExecRepo.UpdateById(ctx, dbSqlExec)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
dbSqlExec.Status = entity.DbSqlExecStatusFail
|
|
|
|
|
|
dbConn, err := d.dbApp.GetDbConn(dbSqlExec.DbId, dbSqlExec.Db)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
dbSqlExec.Res = err.Error()
|
|
|
|
|
|
d.dbSqlExecRepo.UpdateById(ctx, dbSqlExec)
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rowsAffected, err := dbConn.ExecContext(ctx, dbSqlExec.Sql)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
dbSqlExec.Res = err.Error()
|
|
|
|
|
|
d.dbSqlExecRepo.UpdateById(ctx, dbSqlExec)
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
dbSqlExec.Status = entity.DbSqlExecStatusSuccess
|
|
|
|
|
|
dbSqlExec.Res = fmt.Sprintf("执行成功,影响条数: %d", rowsAffected)
|
|
|
|
|
|
return d.dbSqlExecRepo.UpdateById(ctx, dbSqlExec)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-05 14:53:30 +08:00
|
|
|
|
func (d *dbSqlExecAppImpl) DeleteBy(ctx context.Context, condition *entity.DbSqlExec) error {
|
|
|
|
|
|
return d.dbSqlExecRepo.DeleteByCond(ctx, condition)
|
2024-02-29 22:12:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (d *dbSqlExecAppImpl) GetPageList(condition *entity.DbSqlExecQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
|
|
|
|
|
return d.dbSqlExecRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-02-13 21:11:16 +08:00
|
|
|
|
// 保存sql执行记录,如果是查询类则根据系统配置判断是否保存
|
|
|
|
|
|
func (d *dbSqlExecAppImpl) saveSqlExecLog(isQuery bool, dbSqlExecRecord *entity.DbSqlExec) {
|
|
|
|
|
|
if !isQuery {
|
2024-01-23 19:30:28 +08:00
|
|
|
|
d.dbSqlExecRepo.Insert(context.TODO(), dbSqlExecRecord)
|
2023-02-13 21:11:16 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
2024-03-07 17:26:11 +08:00
|
|
|
|
|
|
|
|
|
|
if config.GetDbms().QuerySqlSave {
|
2023-02-13 21:11:16 +08:00
|
|
|
|
dbSqlExecRecord.Table = "-"
|
|
|
|
|
|
dbSqlExecRecord.OldValue = "-"
|
|
|
|
|
|
dbSqlExecRecord.Type = entity.DbSqlExecTypeQuery
|
2024-01-23 19:30:28 +08:00
|
|
|
|
d.dbSqlExecRepo.Insert(context.TODO(), dbSqlExecRecord)
|
2022-09-22 11:56:21 +08:00
|
|
|
|
}
|
2022-06-16 15:55:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
func (d *dbSqlExecAppImpl) doSelect(ctx context.Context, selectStmt *sqlparser.Select, execSqlReq *DbSqlExecReq) (*DbSqlExecRes, error) {
|
2023-02-13 21:11:16 +08:00
|
|
|
|
selectExprsStr := sqlparser.String(selectStmt.SelectExprs)
|
|
|
|
|
|
if selectExprsStr == "*" || strings.Contains(selectExprsStr, ".*") ||
|
|
|
|
|
|
len(strings.Split(selectExprsStr, ",")) > 1 {
|
2023-02-18 23:02:14 +08:00
|
|
|
|
// 如果配置为0,则不校验分页参数
|
2024-03-07 17:26:11 +08:00
|
|
|
|
maxCount := config.GetDbms().MaxResultSet
|
2024-01-24 08:29:16 +00:00
|
|
|
|
// 哪些数据库跳过校验
|
2024-01-29 04:20:23 +00:00
|
|
|
|
skipped := dbi.DbTypeOracle == execSqlReq.DbConn.Info.Type || dbi.DbTypeMssql == execSqlReq.DbConn.Info.Type
|
2024-01-24 08:29:16 +00:00
|
|
|
|
if maxCount != 0 && !skipped {
|
2023-02-18 23:02:14 +08:00
|
|
|
|
limit := selectStmt.Limit
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if limit == nil {
|
|
|
|
|
|
return nil, errorx.NewBiz("请完善分页信息后执行")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-02-18 23:02:14 +08:00
|
|
|
|
count, err := strconv.Atoi(sqlparser.String(limit.Rowcount))
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, errorx.NewBiz("分页参数有误")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if count > maxCount {
|
|
|
|
|
|
return nil, errorx.NewBiz("查询结果集数需小于系统配置的%d条", maxCount)
|
|
|
|
|
|
}
|
2023-02-18 23:02:14 +08:00
|
|
|
|
}
|
2023-02-13 21:11:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
return d.doRead(ctx, execSqlReq)
|
2023-02-13 21:11:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
func (d *dbSqlExecAppImpl) doRead(ctx context.Context, execSqlReq *DbSqlExecReq) (*DbSqlExecRes, error) {
|
2023-09-05 14:41:12 +08:00
|
|
|
|
dbConn := execSqlReq.DbConn
|
2022-09-22 11:56:21 +08:00
|
|
|
|
sql := execSqlReq.Sql
|
2023-12-14 21:27:11 +08:00
|
|
|
|
cols, res, err := dbConn.QueryContext(ctx, sql)
|
2022-09-22 11:56:21 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return &DbSqlExecRes{
|
2023-12-14 21:27:11 +08:00
|
|
|
|
Columns: cols,
|
|
|
|
|
|
Res: res,
|
2022-09-22 11:56:21 +08:00
|
|
|
|
}, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
func (d *dbSqlExecAppImpl) doUpdate(ctx context.Context, update *sqlparser.Update, execSqlReq *DbSqlExecReq, dbSqlExec *entity.DbSqlExec) (*DbSqlExecRes, error) {
|
2023-09-05 14:41:12 +08:00
|
|
|
|
dbConn := execSqlReq.DbConn
|
2022-09-22 11:56:21 +08:00
|
|
|
|
|
2022-06-16 15:55:18 +08:00
|
|
|
|
tableStr := sqlparser.String(update.TableExprs)
|
|
|
|
|
|
// 可能使用别名,故空格切割
|
|
|
|
|
|
tableName := strings.Split(tableStr, " ")[0]
|
2024-01-30 21:56:49 +08:00
|
|
|
|
if strings.Contains(tableName, ".") {
|
2024-01-29 04:20:23 +00:00
|
|
|
|
tableName = strings.Split(tableName, ".")[1]
|
|
|
|
|
|
}
|
2022-06-16 15:55:18 +08:00
|
|
|
|
where := sqlparser.String(update.Where)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if len(where) == 0 {
|
|
|
|
|
|
return nil, errorx.NewBiz("SQL[%s]未执行. 请完善 where 条件后再执行", execSqlReq.Sql)
|
|
|
|
|
|
}
|
2022-06-16 15:55:18 +08:00
|
|
|
|
|
|
|
|
|
|
updateExprs := update.Exprs
|
|
|
|
|
|
updateColumns := make([]string, 0)
|
|
|
|
|
|
for _, v := range updateExprs {
|
|
|
|
|
|
updateColumns = append(updateColumns, v.Name.Name.String())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取表主键列名,排除使用别名
|
2024-03-15 13:31:53 +08:00
|
|
|
|
primaryKey, err := dbConn.GetMetaData().GetPrimaryKey(tableName)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, errorx.NewBiz("获取表主键信息失败")
|
|
|
|
|
|
}
|
2022-06-16 15:55:18 +08:00
|
|
|
|
|
|
|
|
|
|
updateColumnsAndPrimaryKey := strings.Join(updateColumns, ",") + "," + primaryKey
|
|
|
|
|
|
// 查询要更新字段数据的旧值,以及主键值
|
2024-01-29 04:20:23 +00:00
|
|
|
|
selectSql := fmt.Sprintf("SELECT %s FROM %s %s", updateColumnsAndPrimaryKey, tableStr, where)
|
|
|
|
|
|
|
|
|
|
|
|
// WalkQuery查出最多200条数据
|
|
|
|
|
|
maxRec := 200
|
|
|
|
|
|
nowRec := 0
|
|
|
|
|
|
res := make([]map[string]any, 0)
|
2024-04-17 21:28:28 +08:00
|
|
|
|
_, err = dbConn.WalkQueryRows(ctx, selectSql, func(row map[string]any, columns []*dbi.QueryColumn) error {
|
2024-01-29 04:20:23 +00:00
|
|
|
|
nowRec++
|
|
|
|
|
|
res = append(res, row)
|
|
|
|
|
|
if nowRec == maxRec {
|
|
|
|
|
|
return errorx.NewBiz(fmt.Sprintf("超出更新最大查询条数限制: %d", maxRec))
|
|
|
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
logx.Warn(err.Error())
|
2022-11-03 14:05:04 +08:00
|
|
|
|
}
|
2022-06-16 15:55:18 +08:00
|
|
|
|
|
2024-01-29 04:20:23 +00:00
|
|
|
|
dbSqlExec.OldValue = jsonx.ToStr(res)
|
2022-06-16 15:55:18 +08:00
|
|
|
|
dbSqlExec.Table = tableName
|
|
|
|
|
|
dbSqlExec.Type = entity.DbSqlExecTypeUpdate
|
2022-09-22 11:56:21 +08:00
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
return d.doExec(ctx, execSqlReq, dbSqlExec)
|
2022-06-16 15:55:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
func (d *dbSqlExecAppImpl) doDelete(ctx context.Context, delete *sqlparser.Delete, execSqlReq *DbSqlExecReq, dbSqlExec *entity.DbSqlExec) (*DbSqlExecRes, error) {
|
2023-09-05 14:41:12 +08:00
|
|
|
|
dbConn := execSqlReq.DbConn
|
2022-09-22 11:56:21 +08:00
|
|
|
|
|
2022-06-16 15:55:18 +08:00
|
|
|
|
tableStr := sqlparser.String(delete.TableExprs)
|
|
|
|
|
|
// 可能使用别名,故空格切割
|
|
|
|
|
|
table := strings.Split(tableStr, " ")[0]
|
|
|
|
|
|
where := sqlparser.String(delete.Where)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
if len(where) == 0 {
|
|
|
|
|
|
return nil, errorx.NewBiz("SQL[%s]未执行. 请完善 where 条件后再执行", execSqlReq.Sql)
|
|
|
|
|
|
}
|
2022-06-16 15:55:18 +08:00
|
|
|
|
|
|
|
|
|
|
// 查询删除数据
|
|
|
|
|
|
selectSql := fmt.Sprintf("SELECT * FROM %s %s LIMIT 200", tableStr, where)
|
2023-12-07 01:07:34 +08:00
|
|
|
|
_, res, _ := dbConn.QueryContext(ctx, selectSql)
|
2022-06-16 15:55:18 +08:00
|
|
|
|
|
2024-01-09 21:37:56 +08:00
|
|
|
|
dbSqlExec.OldValue = jsonx.ToStr(res)
|
2022-06-16 15:55:18 +08:00
|
|
|
|
dbSqlExec.Table = table
|
|
|
|
|
|
dbSqlExec.Type = entity.DbSqlExecTypeDelete
|
2022-09-22 11:56:21 +08:00
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
return d.doExec(ctx, execSqlReq, dbSqlExec)
|
2022-06-16 15:55:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
func (d *dbSqlExecAppImpl) doInsert(ctx context.Context, insert *sqlparser.Insert, execSqlReq *DbSqlExecReq, dbSqlExec *entity.DbSqlExec) (*DbSqlExecRes, error) {
|
2022-06-16 15:55:18 +08:00
|
|
|
|
tableStr := sqlparser.String(insert.Table)
|
|
|
|
|
|
// 可能使用别名,故空格切割
|
|
|
|
|
|
table := strings.Split(tableStr, " ")[0]
|
|
|
|
|
|
dbSqlExec.Table = table
|
|
|
|
|
|
dbSqlExec.Type = entity.DbSqlExecTypeInsert
|
2022-09-22 11:56:21 +08:00
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
return d.doExec(ctx, execSqlReq, dbSqlExec)
|
2022-09-22 11:56:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
func (d *dbSqlExecAppImpl) doExec(ctx context.Context, execSqlReq *DbSqlExecReq, dbSqlExecRecord *entity.DbSqlExec) (*DbSqlExecRes, error) {
|
|
|
|
|
|
dbConn := execSqlReq.DbConn
|
2024-05-08 21:04:25 +08:00
|
|
|
|
|
|
|
|
|
|
if flowProcdefId := d.flowProcdefApp.GetProcdefIdByCodePath(ctx, dbConn.Info.CodePath...); flowProcdefId != 0 {
|
2024-02-29 22:12:50 +08:00
|
|
|
|
bizKey := stringx.Rand(24)
|
|
|
|
|
|
// 如果该库关联了审批流程,则启动流程实例即可
|
2024-05-08 21:04:25 +08:00
|
|
|
|
_, err := d.flowProcinstApp.StartProc(ctx, flowProcdefId, &flowapp.StarProcParam{
|
2024-02-29 22:12:50 +08:00
|
|
|
|
BizType: DbSqlExecFlowBizType,
|
|
|
|
|
|
BizKey: bizKey,
|
|
|
|
|
|
Remark: dbSqlExecRecord.Remark,
|
|
|
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
dbSqlExecRecord.FlowBizKey = bizKey
|
|
|
|
|
|
dbSqlExecRecord.Status = entity.DbSqlExecStatusWait
|
|
|
|
|
|
return nil, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sql := execSqlReq.Sql
|
2023-12-07 01:07:34 +08:00
|
|
|
|
rowsAffected, err := dbConn.ExecContext(ctx, sql)
|
2022-11-02 19:27:40 +08:00
|
|
|
|
execRes := "success"
|
2022-09-22 11:56:21 +08:00
|
|
|
|
if err != nil {
|
2022-11-02 19:27:40 +08:00
|
|
|
|
execRes = err.Error()
|
2024-02-29 22:12:50 +08:00
|
|
|
|
dbSqlExecRecord.Status = entity.DbSqlExecStatusFail
|
2024-03-02 19:08:19 +08:00
|
|
|
|
dbSqlExecRecord.Res = execRes
|
2024-02-29 22:12:50 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
dbSqlExecRecord.Res = fmt.Sprintf("执行成功,影响条数: %d", rowsAffected)
|
2022-09-22 11:56:21 +08:00
|
|
|
|
}
|
2023-06-01 12:31:32 +08:00
|
|
|
|
res := make([]map[string]any, 0)
|
|
|
|
|
|
resData := make(map[string]any)
|
2022-11-02 19:27:40 +08:00
|
|
|
|
resData["rowsAffected"] = rowsAffected
|
|
|
|
|
|
resData["sql"] = sql
|
|
|
|
|
|
resData["result"] = execRes
|
2022-09-22 11:56:21 +08:00
|
|
|
|
res = append(res, resData)
|
|
|
|
|
|
|
|
|
|
|
|
return &DbSqlExecRes{
|
2024-01-12 13:15:30 +08:00
|
|
|
|
Columns: []*dbi.QueryColumn{
|
2023-12-14 21:27:11 +08:00
|
|
|
|
{Name: "sql", Type: "string"},
|
|
|
|
|
|
{Name: "rowsAffected", Type: "number"},
|
|
|
|
|
|
{Name: "result", Type: "string"},
|
|
|
|
|
|
},
|
|
|
|
|
|
Res: res,
|
2022-12-17 22:24:21 +08:00
|
|
|
|
}, err
|
2022-06-16 15:55:18 +08:00
|
|
|
|
}
|