Browse Source

添加sql执行

yjp 1 year ago
parent
commit
d92eacc8d6

+ 17 - 0
convenient/data_containers/sql_executor.yaml

@@ -0,0 +1,17 @@
+kind: DataContainer
+spec:
+  namespace: # 替换
+  data_source: # 替换
+  name: # 替换.sql_execute_logs
+  spec:
+    table_name: # 替换.sql_execute_logs
+    columns:
+      - name: sql
+        type: text
+        comment: sql语句
+      - name: executor_name
+        type: varchar(256)
+        comment: 执行人姓名
+      - name: executed_time
+        type: "timestamp with time zone"
+        comment: 执行时间

+ 137 - 0
convenient/domain/sql_executor/api.go

@@ -1 +1,138 @@
 package sql_executor
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/binding/request"
+	"git.sxidc.com/go-framework/baize/framework/binding/response"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/domain"
+	"git.sxidc.com/go-framework/baize/framework/core/infrastructure"
+	"git.sxidc.com/go-framework/baize/framework/core/infrastructure/database"
+	"git.sxidc.com/go-framework/baize/framework/core/infrastructure/database/sql"
+	"git.sxidc.com/go-tools/utils/strutils"
+)
+
+// Simple Bind参数
+type Simple struct {
+	// schema
+	Schema string
+}
+
+func (simple *Simple) bind(binder *binding.Binder) {
+	sqlExecuteLogTableName := domain.TableName(simple.Schema, &SqlExecuteLog{})
+
+	binding.PostBind(binder, &binding.SimpleBindItem[map[string]any]{
+		Path:          "/sql/execute",
+		ResponseFunc:  response.SendMapResponse,
+		RequestParams: &ExecuteSqlJsonBody{},
+		ServiceFunc: func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (map[string]any, error) {
+			errResponse := map[string]any{
+				"result": make([]sql.Result, 0),
+			}
+
+			dbExecutor := i.DBExecutor()
+
+			jsonBody, err := request.ToConcrete[*ExecuteSqlJsonBody](params)
+			if err != nil {
+				return errResponse, err
+			}
+
+			var results []sql.Result
+
+			err = database.Transaction(dbExecutor, func(tx database.Executor) error {
+				innerResults, err := database.ExecuteRawSql(tx, jsonBody.Sql, nil)
+				if err != nil {
+					return err
+				}
+
+				sqlExecuteLog := &SqlExecuteLog{
+					Sql:          jsonBody.Sql,
+					ExecutorName: jsonBody.ExecutorName,
+				}
+
+				err = sqlExecuteLog.ForCreate()
+				if err != nil {
+					return err
+				}
+
+				err = database.InsertEntity(tx, sqlExecuteLogTableName, sqlExecuteLog)
+				if err != nil {
+					return err
+				}
+
+				results = innerResults
+
+				return nil
+			})
+			if err != nil {
+				return errResponse, err
+			}
+
+			return map[string]any{
+				"result": results,
+			}, nil
+		},
+	})
+
+	binding.GetBind(binder, &binding.SimpleBindItem[response.InfosData[SqlExecuteLogInfo]]{
+		Path:          "/sql/execute/log",
+		ResponseFunc:  response.SendInfosResponse[SqlExecuteLogInfo],
+		RequestParams: &QuerySqlExecuteLogQueryParams{},
+		ServiceFunc: func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (response.InfosData[SqlExecuteLogInfo], error) {
+			errResponse := response.InfosData[SqlExecuteLogInfo]{
+				Infos: make([]SqlExecuteLogInfo, 0),
+			}
+
+			dbExecutor := i.DBExecutor()
+
+			queryParams, err := request.ToConcrete[*QuerySqlExecuteLogQueryParams](params)
+			if err != nil {
+				return errResponse, err
+			}
+
+			conditions := sql.NewConditions()
+
+			if strutils.IsStringNotEmpty(queryParams.Sql) {
+				conditions.Like(ColumnSql, "%"+queryParams.Sql+"%")
+			}
+
+			if strutils.IsStringNotEmpty(queryParams.ExecutorName) {
+				conditions.Like(ColumnExecutorName, "%"+queryParams.ExecutorName+"%")
+			}
+
+			if strutils.IsStringNotEmpty(queryParams.StartExecuteTime) {
+				conditions.GreaterThanAndEqual(ColumnExecutedTime, queryParams.StartExecuteTime)
+			}
+
+			if strutils.IsStringNotEmpty(queryParams.EndExecuteTime) {
+				conditions.LessThanAndEqual(ColumnExecutedTime, queryParams.EndExecuteTime)
+			}
+
+			results, totalCount, err := database.Query(dbExecutor, &sql.QueryExecuteParams{
+				TableName:  sqlExecuteLogTableName,
+				Conditions: conditions,
+				PageNo:     queryParams.PageNo,
+				PageSize:   queryParams.PageSize,
+			})
+			if err != nil {
+				return errResponse, nil
+			}
+
+			infos := make([]SqlExecuteLogInfo, 0)
+			err = sql.ParseSqlResult(results, &infos)
+			if err != nil {
+				return errResponse, nil
+			}
+
+			return response.InfosData[SqlExecuteLogInfo]{
+				Infos:      infos,
+				TotalCount: totalCount,
+				PageNo:     queryParams.PageNo,
+			}, nil
+		},
+	})
+}
+
+func BindSqlExecutor(binder *binding.Binder, simple *Simple) {
+	simple.bind(binder)
+}

+ 68 - 0
convenient/domain/sql_executor/entity.go

@@ -1 +1,69 @@
 package sql_executor
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/core/domain/value_object"
+	"git.sxidc.com/go-tools/utils/strutils"
+	"git.sxidc.com/service-supports/fserr"
+	"time"
+)
+
+const (
+	ColumnSql          = "sql"
+	ColumnExecutorName = "executor_name"
+	ColumnExecutedTime = "executed_time"
+)
+
+const (
+	fieldExecutorNameLen = 256
+)
+
+type SqlExecuteLog struct {
+	value_object.Base
+	Sql          string    `sqlmapping:"column:sql;" sqlresult:"column:sql;"`
+	ExecutorName string    `sqlmapping:"column:executor_name;" sqlresult:"column:executor_name;"`
+	ExecutedTime time.Time `sqlmapping:"column:executed_time;" sqlresult:"column:executed_time;"`
+}
+
+func (e *SqlExecuteLog) DomainCNName() string {
+	return "SQL日志"
+}
+
+func (e *SqlExecuteLog) DomainCamelName() string {
+	return "SqlExecuteLog"
+}
+
+func (e *SqlExecuteLog) ForCreate() error {
+	err := e.checkFieldSql()
+	if err != nil {
+		return err
+	}
+
+	err = e.checkFieldExecutorName()
+	if err != nil {
+		return err
+	}
+
+	e.ExecutedTime = time.Now().Local()
+
+	return nil
+}
+
+func (e *SqlExecuteLog) checkFieldSql() error {
+	if strutils.IsStringEmpty(e.Sql) {
+		return fserr.New(e.DomainCNName() + "sql为空")
+	}
+
+	return nil
+}
+
+func (e *SqlExecuteLog) checkFieldExecutorName() error {
+	if strutils.IsStringEmpty(e.ExecutorName) {
+		return fserr.New(e.DomainCNName() + "执行人姓名为空")
+	}
+
+	if len(e.ExecutorName) > fieldExecutorNameLen {
+		return fserr.New(e.DomainCNName() + "执行人姓名超出限定长度")
+	}
+
+	return nil
+}

+ 7 - 0
convenient/domain/sql_executor/info.go

@@ -0,0 +1,7 @@
+package sql_executor
+
+type SqlExecuteLogInfo struct {
+	Sql          string `json:"sql" sqlresult:"sql"`
+	ExecutorName string `json:"executorName" sqlresult:"executor_name"`
+	ExecutedTime string `json:"executedTime" sqlresult:"executed_time"`
+}

+ 12 - 2
convenient/domain/sql_executor/request_params.go

@@ -1,6 +1,16 @@
 package sql_executor
 
+import "git.sxidc.com/go-framework/baize/framework/binding/request"
+
 type ExecuteSqlJsonBody struct {
-	Sql        string `json:"sql"`
-	OperatorID string `json:"operatorId"`
+	Sql          string `json:"sql" binding:"required"`
+	ExecutorName string `json:"executorName" binding:"required"`
+}
+
+type QuerySqlExecuteLogQueryParams struct {
+	request.BaseQueryParams
+	Sql              string `form:"sql"`
+	ExecutorName     string `form:"executorName"`
+	StartExecuteTime string `form:"startExecuteTime"`
+	EndExecuteTime   string `form:"endExecuteTime"`
 }

+ 1 - 1
convenient/domain_gateway/configuration.go

@@ -5,7 +5,7 @@ import (
 	"git.sxidc.com/go-framework/baize/framework/gateway"
 )
 
-func configurationGatewayAPI(baseUrl string, builder *gateway.Builder) {
+func configurationGatewayApi(baseUrl string, builder *gateway.Builder) {
 	gwtools.CRUD(builder, &gwtools.CRUDParams{
 		ServiceVersionedUrl: baseUrl,
 		DomainCamelName:     "Configuration",

+ 22 - 0
convenient/domain_gateway/sql_executor.go

@@ -0,0 +1,22 @@
+package domain_gateway
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/gwtools"
+	"git.sxidc.com/go-framework/baize/framework/gateway"
+)
+
+func sqlExecutorGatewayApi(baseUrl string, builder *gateway.Builder) {
+	gwtools.PostPassThrough(builder, &gwtools.SimplePassThroughParams{
+		RelativePath: "/sql/execute",
+		Request: &gateway.PostRequest{
+			Url: baseUrl + "/sql/execute",
+		},
+	})
+
+	gwtools.GetPassThrough(builder, &gwtools.SimplePassThroughParams{
+		RelativePath: "/sql/execute/log",
+		Request: &gateway.GetRequest{
+			Url: baseUrl + "/sql/execute/log",
+		},
+	})
+}

+ 16 - 8
convenient/gwtools/common.go

@@ -7,11 +7,19 @@ import (
 	"git.sxidc.com/service-supports/fserr"
 )
 
-type GetTenantIDFunc func(c *api.Context) (string, error)
-type GetUserIDFunc func(c *api.Context) (string, error)
+type TenantInfo interface {
+	GetID() string
+}
+
+type UserInfo interface {
+	GetID() string
+}
+
+type GetTenantInfoFunc func(c *api.Context) (TenantInfo, error)
+type GetUserInfoFunc func(c *api.Context) (UserInfo, error)
 
 func AddBodyTenantIDAndUserID(tenantIDFieldName string, userIDFieldName string,
-	getTenantIDFunc GetTenantIDFunc, getUserIDFunc GetUserIDFunc) gateway.FormBodyFunc {
+	getTenantIDFunc GetTenantInfoFunc, getUserIDFunc GetUserInfoFunc) gateway.FormBodyFunc {
 	return func(c *api.Context, historyRequests []gateway.BuilderRequest, customResultMap map[string]any) (any, error) {
 		body, err := gateway.DefaultFormBodyFunc(c, historyRequests, customResultMap)
 		if err != nil {
@@ -72,7 +80,7 @@ func AddBodyTenantIDAndUserID(tenantIDFieldName string, userIDFieldName string,
 }
 
 func AddQueryParamsTenantIDAndUserID(tenantIDFieldName string, userIDFieldName string,
-	getTenantIDFunc GetTenantIDFunc, getUserIDFunc GetUserIDFunc) gateway.FormQueryParamsFunc {
+	getTenantIDFunc GetTenantInfoFunc, getUserIDFunc GetUserInfoFunc) gateway.FormQueryParamsFunc {
 	return func(c *api.Context, historyRequests []gateway.BuilderRequest, customResultMap map[string]any) (map[string]string, error) {
 		queryParams, err := gateway.DefaultFormQueryParamsFunc(c, historyRequests, customResultMap)
 		if err != nil {
@@ -86,24 +94,24 @@ func AddQueryParamsTenantIDAndUserID(tenantIDFieldName string, userIDFieldName s
 		if getTenantIDFunc != nil {
 			_, ok := queryParams[tenantIDFieldName]
 			if !ok {
-				tenantID, err := getTenantIDFunc(c)
+				tenantInfo, err := getTenantIDFunc(c)
 				if err != nil {
 					return nil, err
 				}
 
-				queryParams[tenantIDFieldName] = tenantID
+				queryParams[tenantIDFieldName] = tenantInfo.GetID()
 			}
 		}
 
 		if getUserIDFunc != nil {
 			_, ok := queryParams[userIDFieldName]
 			if !ok {
-				userID, err := getUserIDFunc(c)
+				userInfo, err := getUserIDFunc(c)
 				if err != nil {
 					return nil, err
 				}
 
-				queryParams[userIDFieldName] = userID
+				queryParams[userIDFieldName] = userInfo.GetID()
 			}
 		}
 

+ 8 - 8
convenient/gwtools/crud.go

@@ -139,10 +139,10 @@ type CRUDCreateOptions struct {
 	middlewares []api.Handler
 
 	// 获取租户ID的接口
-	getTenantIDFunc GetTenantIDFunc
+	getTenantIDFunc GetTenantInfoFunc
 
 	// 获取用户ID的接口
-	getUserIDFunc GetUserIDFunc
+	getUserIDFunc GetUserInfoFunc
 }
 
 type CRUDDeleteOptions struct {
@@ -167,7 +167,7 @@ type CRUDUpdateOptions struct {
 	middlewares []api.Handler
 
 	// 获取用户ID的接口
-	getUserIDFunc GetUserIDFunc
+	getUserIDFunc GetUserInfoFunc
 }
 
 type CRUDQueryOptions struct {
@@ -181,7 +181,7 @@ type CRUDQueryOptions struct {
 	middlewares []api.Handler
 
 	// 获取租户ID的接口
-	getTenantIDFunc GetTenantIDFunc
+	getTenantIDFunc GetTenantInfoFunc
 }
 
 type CRUDGetByIDOptions struct {
@@ -207,13 +207,13 @@ func WithCRUDCreateMiddlewares(middlewares []api.Handler) CRUDCreateOption {
 	}
 }
 
-func WithCRUDCreateGetTenantIDFunc(getTenantIDFunc GetTenantIDFunc) CRUDCreateOption {
+func WithCRUDCreateGetTenantIDFunc(getTenantIDFunc GetTenantInfoFunc) CRUDCreateOption {
 	return func(options *CRUDCreateOptions) {
 		options.getTenantIDFunc = getTenantIDFunc
 	}
 }
 
-func WithCRUDCreateGetUserIDFunc(getUserIDFunc GetUserIDFunc) CRUDCreateOption {
+func WithCRUDCreateGetUserIDFunc(getUserIDFunc GetUserInfoFunc) CRUDCreateOption {
 	return func(options *CRUDCreateOptions) {
 		options.getUserIDFunc = getUserIDFunc
 	}
@@ -255,7 +255,7 @@ func WithCRUDUpdateMiddlewares(middlewares []api.Handler) CRUDUpdateOption {
 	}
 }
 
-func WithCRUDUpdateGetUserIDFunc(getUserIDFunc GetUserIDFunc) CRUDUpdateOption {
+func WithCRUDUpdateGetUserIDFunc(getUserIDFunc GetUserInfoFunc) CRUDUpdateOption {
 	return func(options *CRUDUpdateOptions) {
 		options.getUserIDFunc = getUserIDFunc
 	}
@@ -279,7 +279,7 @@ func WithCRUDQueryMiddlewares(middlewares []api.Handler) CRUDQueryOption {
 	}
 }
 
-func WithCRUDQueryGetTenantIDFunc(getTenantIDFunc GetTenantIDFunc) CRUDQueryOption {
+func WithCRUDQueryGetTenantIDFunc(getTenantIDFunc GetTenantInfoFunc) CRUDQueryOption {
 	return func(options *CRUDQueryOptions) {
 		options.getTenantIDFunc = getTenantIDFunc
 	}

+ 2 - 2
convenient/gwtools/one2many.go

@@ -121,7 +121,7 @@ type One2ManyOptions struct {
 	disableRightWithLeftQuery bool
 
 	// 获取租户ID的接口
-	rightWithLeftQueryGetTenantIDFunc GetTenantIDFunc
+	rightWithLeftQueryGetTenantIDFunc GetTenantInfoFunc
 }
 
 func WithOne2ManyDisableLeft() One2ManyOption {
@@ -166,7 +166,7 @@ func WithOne2ManyDisableRightWithLeftQuery() One2ManyOption {
 	}
 }
 
-func WithOne2ManyRightWithLeftQueryGetTenantIDFunc(getTenantIDFunc GetTenantIDFunc) One2OneOption {
+func WithOne2ManyRightWithLeftQueryGetTenantIDFunc(getTenantIDFunc GetTenantInfoFunc) One2OneOption {
 	return func(options *One2OneOptions) {
 		options.rightWithLeftQueryGetTenantIDFunc = getTenantIDFunc
 	}

+ 4 - 4
convenient/gwtools/one2one.go

@@ -136,10 +136,10 @@ type One2OneOptions struct {
 	disableRightWithLeftQuery bool
 
 	// 获取租户ID的接口
-	leftWithRightQueryGetTenantIDFunc GetTenantIDFunc
+	leftWithRightQueryGetTenantIDFunc GetTenantInfoFunc
 
 	// 获取租户ID的接口
-	rightWithLeftQueryGetTenantIDFunc GetTenantIDFunc
+	rightWithLeftQueryGetTenantIDFunc GetTenantInfoFunc
 }
 
 func WithOne2OneDisableLeft() One2OneOption {
@@ -190,13 +190,13 @@ func WithOne2OneDisableRightWithLeftQuery() One2OneOption {
 	}
 }
 
-func WithOne2OneLeftWithRightQueryGetTenantIDFunc(getTenantIDFunc GetTenantIDFunc) One2OneOption {
+func WithOne2OneLeftWithRightQueryGetTenantIDFunc(getTenantIDFunc GetTenantInfoFunc) One2OneOption {
 	return func(options *One2OneOptions) {
 		options.leftWithRightQueryGetTenantIDFunc = getTenantIDFunc
 	}
 }
 
-func WithOne2OneRightWithLeftQueryGetTenantIDFunc(getTenantIDFunc GetTenantIDFunc) One2OneOption {
+func WithOne2OneRightWithLeftQueryGetTenantIDFunc(getTenantIDFunc GetTenantInfoFunc) One2OneOption {
 	return func(options *One2OneOptions) {
 		options.rightWithLeftQueryGetTenantIDFunc = getTenantIDFunc
 	}

+ 0 - 16
framework/core/domain/value_object/base.go

@@ -5,19 +5,3 @@ type Base struct{}
 func (valueObject *Base) DBSchema() string {
 	return ""
 }
-
-func (valueObject *Base) DomainCNName() string {
-	panic("值对象没有实现DomainCNName接口")
-}
-
-func (valueObject *Base) DomainCamelName() string {
-	panic("值对象没有实现DomainCamelName接口")
-}
-
-func (valueObject *Base) CheckKeyFields() error {
-	panic("值对象没有实现CheckKeyFields接口")
-}
-
-func (valueObject *Base) ForCreate() error {
-	panic("值对象没有实现ForCreate接口")
-}