mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
feat: oracle支持服务名、数据库执行超时时间配置等
This commit is contained in:
@@ -15,12 +15,12 @@ require (
|
||||
github.com/go-playground/universal-translator v0.18.1
|
||||
github.com/go-playground/validator/v10 v10.14.0
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/kanzihuang/vitess/go/vt/sqlparser v0.0.0-20231018071450-ac8d9f0167e9
|
||||
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20230712084735-068dc2aee82d
|
||||
github.com/microsoft/go-mssqldb v1.6.0
|
||||
github.com/microsoft/go-mssqldb v1.7.0
|
||||
github.com/mojocn/base64Captcha v1.3.6 // 验证码
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/sftp v1.13.6
|
||||
@@ -30,7 +30,7 @@ require (
|
||||
github.com/sijms/go-ora/v2 v2.8.9
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.mongodb.org/mongo-driver v1.14.0 // mongo
|
||||
golang.org/x/crypto v0.20.0 // ssh
|
||||
golang.org/x/crypto v0.21.0 // ssh
|
||||
golang.org/x/oauth2 v0.17.0
|
||||
golang.org/x/sync v0.6.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
@@ -87,7 +87,7 @@ require (
|
||||
golang.org/x/exp v0.0.0-20230519143937-03e91628a987 // indirect
|
||||
golang.org/x/image v0.13.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230131230820-1c016267d619 // indirect
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"mayfly-go/internal/db/api/form"
|
||||
"mayfly-go/internal/db/api/vo"
|
||||
"mayfly-go/internal/db/application"
|
||||
"mayfly-go/internal/db/config"
|
||||
"mayfly-go/internal/db/dbm/dbi"
|
||||
"mayfly-go/internal/db/domain/entity"
|
||||
msgapp "mayfly-go/internal/msg/application"
|
||||
@@ -113,7 +114,7 @@ func (d *Db) ExecSql(rc *req.Ctx) {
|
||||
}
|
||||
|
||||
// 比前端超时时间稍微快一点,可以提示到前端
|
||||
ctx, cancel := context.WithTimeout(rc.MetaCtx, 58*time.Second)
|
||||
ctx, cancel := context.WithTimeout(rc.MetaCtx, time.Duration(config.GetDbms().SqlExecTl)*time.Second)
|
||||
defer cancel()
|
||||
|
||||
sqls, err := sqlparser.SplitStatementToPieces(sql, sqlparser.WithDialect(dbConn.Info.Type.Dialect()))
|
||||
|
||||
@@ -6,7 +6,7 @@ type InstanceForm struct {
|
||||
Type string `binding:"required" json:"type"` // 类型,mysql oracle等
|
||||
Host string `binding:"required" json:"host"`
|
||||
Port int `json:"port"`
|
||||
Sid string `json:"sid"`
|
||||
Extra string `json:"extra"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Params string `json:"params"`
|
||||
|
||||
@@ -8,8 +8,8 @@ type InstanceListVO struct {
|
||||
Host *string `json:"host"`
|
||||
Port *int `json:"port"`
|
||||
Type *string `json:"type"`
|
||||
Params *string `json:"params"`
|
||||
Sid *string `json:"sid"`
|
||||
Params string `json:"params"`
|
||||
Extra string `json:"extra"`
|
||||
Username *string `json:"username"`
|
||||
Remark *string `json:"remark"`
|
||||
CreateTime *time.Time `json:"createTime"`
|
||||
|
||||
@@ -199,7 +199,6 @@ func (d *dbAppImpl) GetDbConnByInstanceId(instanceId uint64) (*dbi.DbConn, error
|
||||
func toDbInfo(instance *entity.DbInstance, dbId uint64, database string, tagPath ...string) *dbi.DbInfo {
|
||||
di := new(dbi.DbInfo)
|
||||
di.InstanceId = instance.Id
|
||||
di.Sid = instance.Sid
|
||||
di.Id = dbId
|
||||
di.Database = database
|
||||
di.TagPath = tagPath
|
||||
|
||||
@@ -95,7 +95,7 @@ func (d *dbSqlExecAppImpl) Exec(ctx context.Context, execSqlReq *DbSqlExecReq) (
|
||||
isSelect := strings.HasPrefix(lowerSql, "select")
|
||||
if isSelect {
|
||||
// 如果配置为0,则不校验分页参数
|
||||
maxCount := config.GetDbQueryMaxCount()
|
||||
maxCount := config.GetDbms().MaxResultSet
|
||||
if maxCount != 0 {
|
||||
if !strings.Contains(lowerSql, "limit") &&
|
||||
// 兼容oracle rownum分页
|
||||
@@ -207,7 +207,8 @@ func (d *dbSqlExecAppImpl) saveSqlExecLog(isQuery bool, dbSqlExecRecord *entity.
|
||||
d.dbSqlExecRepo.Insert(context.TODO(), dbSqlExecRecord)
|
||||
return
|
||||
}
|
||||
if config.GetDbSaveQuerySql() {
|
||||
|
||||
if config.GetDbms().QuerySqlSave {
|
||||
dbSqlExecRecord.Table = "-"
|
||||
dbSqlExecRecord.OldValue = "-"
|
||||
dbSqlExecRecord.Type = entity.DbSqlExecTypeQuery
|
||||
@@ -220,7 +221,7 @@ func (d *dbSqlExecAppImpl) doSelect(ctx context.Context, selectStmt *sqlparser.S
|
||||
if selectExprsStr == "*" || strings.Contains(selectExprsStr, ".*") ||
|
||||
len(strings.Split(selectExprsStr, ",")) > 1 {
|
||||
// 如果配置为0,则不校验分页参数
|
||||
maxCount := config.GetDbQueryMaxCount()
|
||||
maxCount := config.GetDbms().MaxResultSet
|
||||
// 哪些数据库跳过校验
|
||||
skipped := dbi.DbTypeOracle == execSqlReq.DbConn.Info.Type || dbi.DbTypeMssql == execSqlReq.DbConn.Info.Type
|
||||
if maxCount != 0 && !skipped {
|
||||
|
||||
@@ -2,26 +2,33 @@ package config
|
||||
|
||||
import (
|
||||
sysapp "mayfly-go/internal/sys/application"
|
||||
"mayfly-go/pkg/utils/conv"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
ConfigKeyDbSaveQuerySQL string = "DbSaveQuerySQL" // 数据库是否记录查询相关sql
|
||||
ConfigKeyDbQueryMaxCount string = "DbQueryMaxCount" // 数据库查询的最大数量
|
||||
ConfigKeyDbms string = "DbmsConfig" // dbms相关配置信息
|
||||
ConfigKeyDbBackupRestore string = "DbBackupRestore" // 数据库备份
|
||||
ConfigKeyDbMysqlBin string = "MysqlBin" // mysql可执行文件配置
|
||||
ConfigKeyDbMariadbBin string = "MariadbBin" // mariadb可执行文件配置
|
||||
)
|
||||
|
||||
// 获取数据库最大查询数量配置
|
||||
func GetDbQueryMaxCount() int {
|
||||
return sysapp.GetConfigApp().GetConfig(ConfigKeyDbQueryMaxCount).IntValue(200)
|
||||
type Dbms struct {
|
||||
QuerySqlSave bool // 是否记录查询类sql
|
||||
MaxResultSet int // 允许sql查询的最大结果集数。注: 0=不限制
|
||||
SqlExecTl int // sql执行时间限制,超过该时间(单位:秒),执行将被取消
|
||||
}
|
||||
|
||||
// 获取数据库是否记录查询相关sql配置
|
||||
func GetDbSaveQuerySql() bool {
|
||||
return sysapp.GetConfigApp().GetConfig(ConfigKeyDbSaveQuerySQL).BoolValue(false)
|
||||
func GetDbms() *Dbms {
|
||||
c := sysapp.GetConfigApp().GetConfig(ConfigKeyDbms)
|
||||
jm := c.GetJsonMap()
|
||||
|
||||
dbmsConf := new(Dbms)
|
||||
dbmsConf.QuerySqlSave = c.ConvBool(jm["querySqlSave"], false)
|
||||
dbmsConf.MaxResultSet = conv.Str2Int(jm["maxResultSet"], 0)
|
||||
dbmsConf.SqlExecTl = conv.Str2Int(jm["sqlExecTl"], 60)
|
||||
return dbmsConf
|
||||
}
|
||||
|
||||
type DbBackupRestore struct {
|
||||
|
||||
@@ -16,7 +16,7 @@ type DbInfo struct {
|
||||
Type DbType // 类型,mysql postgres等
|
||||
Host string
|
||||
Port int
|
||||
Sid string // oracle数据库需要指定sid
|
||||
Extra string // 连接需要的其他额外参数(json字符串),如oracle数据库需要指定sid
|
||||
Network string
|
||||
Username string
|
||||
Password string
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"mayfly-go/internal/db/dbm/dbi"
|
||||
"mayfly-go/pkg/utils/anyx"
|
||||
"mayfly-go/pkg/utils/jsonx"
|
||||
"strings"
|
||||
|
||||
go_ora "github.com/sijms/go-ora/v2"
|
||||
@@ -17,12 +19,11 @@ type OraMeta struct {
|
||||
}
|
||||
|
||||
func (md *OraMeta) GetSqlDb(d *dbi.DbInfo) (*sql.DB, error) {
|
||||
driverName := "oracle"
|
||||
|
||||
err := d.IfUseSshTunnelChangeIpPort()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 参数参考 https://github.com/sijms/go-ora?tab=readme-ov-file#other-connection-options
|
||||
urlOptions := make(map[string]string)
|
||||
|
||||
@@ -50,9 +51,20 @@ func (md *OraMeta) GetSqlDb(d *dbi.DbInfo) (*sql.DB, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 从extra获取sid或serviceName
|
||||
serviceName := ""
|
||||
if d.Extra != "" {
|
||||
extraMap := jsonx.ToMap(d.Extra)
|
||||
serviceName = anyx.ConvString(extraMap["serviceName"])
|
||||
if sid := anyx.ConvString(extraMap["sid"]); sid != "" {
|
||||
urlOptions["SID"] = sid
|
||||
}
|
||||
}
|
||||
|
||||
urlOptions["TIMEOUT"] = "1000"
|
||||
connStr := go_ora.BuildUrl(d.Host, d.Port, d.Sid, d.Username, d.Password, urlOptions)
|
||||
conn, err := sql.Open(driverName, connStr)
|
||||
connStr := go_ora.BuildUrl(d.Host, d.Port, serviceName, d.Username, d.Password, urlOptions)
|
||||
conn, err := sql.Open("oracle", connStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ type DbInstance struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Network string `json:"network"`
|
||||
Sid string `json:"sid"`
|
||||
Extra *string `json:"extra"` // 连接需要的其他额外参数(json格式), 如oracle需要sid等
|
||||
Username string `json:"username"`
|
||||
Password string `json:"-"`
|
||||
Params *string `json:"params"`
|
||||
|
||||
@@ -18,7 +18,7 @@ func newConfigRepo() repository.Config {
|
||||
|
||||
func (m *configRepoImpl) GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||
qd := gormx.NewQuery(condition).
|
||||
Eq("key", condition.Key).
|
||||
Like("`key`", condition.Key).
|
||||
And("permission = 'all' OR permission LIKE ?", "%"+condition.Permission+",%").
|
||||
WithOrderBy(orderBy...)
|
||||
return gormx.PageQuery(qd, pageParam, toEntity)
|
||||
|
||||
@@ -88,7 +88,7 @@ func (wf *wrapperF) QueryIntDefault(qm string, defaultInt int) int {
|
||||
|
||||
// 获取分页参数
|
||||
func (wf *wrapperF) GetPageParam() *model.PageParam {
|
||||
return &model.PageParam{PageNum: wf.QueryIntDefault("pageNum", 1), PageSize: wf.QueryIntDefault("pageSize", 10)}
|
||||
return &model.PageParam{PageNum: wf.QueryIntDefault("pageNum", 1), PageSize: wf.QueryIntDefault("pageSize", 100)}
|
||||
}
|
||||
|
||||
// 获取路径参数
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
服务启动&重启:./startup.sh
|
||||
服务关闭:./shutdown.sh
|
||||
|
||||
直接通过 host:ip即可访问项目
|
||||
直接通过 host:config.yml里配置的端口 即可访问项目
|
||||
初始账号 admin/admin123.
|
||||
9
server/resources/script/sql/v1.7/v1.7.5.sql
Normal file
9
server/resources/script/sql/v1.7/v1.7.5.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
DELETE
|
||||
FROM `t_sys_config`
|
||||
WHERE `key` in ('DbQueryMaxCount', 'DbSaveQuerySQL');
|
||||
|
||||
INSERT INTO `t_sys_config` (`name`, `key`, `params`, `value`, `remark`, `permission`, `create_time`, `creator_id`, `creator`, `update_time`, `modifier_id`, `modifier`, `is_deleted`, `delete_time`) VALUES('DBMS配置', 'DbmsConfig', '[{"model":"querySqlSave","name":"记录查询sql","placeholder":"是否记录查询类sql","options":"true,false"},{"model":"maxResultSet","name":"最大结果集","placeholder":"允许sql查询的最大结果集数。注: 0=不限制","options":""},{"model":"sqlExecTl","name":"sql执行时间限制","placeholder":"超过该时间(单位:秒),执行将被取消"}]', '{"querySqlSave":"false","maxResultSet":"0","sqlExecTl":"60"}', 'DBMS相关配置', 'admin,', '2024-03-06 13:30:51', 1, 'admin', '2024-03-06 14:07:16', 1, 'admin', 0, NULL);
|
||||
|
||||
ALTER TABLE t_db_instance CHANGE sid extra varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL COMMENT '连接需要的额外参数,如oracle数据库需要sid等';
|
||||
ALTER TABLE t_db_instance MODIFY COLUMN extra varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL COMMENT '连接需要的额外参数,如oracle数据库需要sid等';
|
||||
Reference in New Issue
Block a user