增加InputParam验证
This commit is contained in:
parent
ce189a9067
commit
bc99c08d55
@ -13,6 +13,7 @@ import (
|
|||||||
"git.zhangdeman.cn/zhangdeman/consts"
|
"git.zhangdeman.cn/zhangdeman/consts"
|
||||||
"git.zhangdeman.cn/zhangdeman/database/abstract"
|
"git.zhangdeman.cn/zhangdeman/database/abstract"
|
||||||
"git.zhangdeman.cn/zhangdeman/database/define"
|
"git.zhangdeman.cn/zhangdeman/database/define"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -121,5 +122,69 @@ func (e *execute) Delete(ctx context.Context, inputParam *define.Api2SqlParam) (
|
|||||||
//
|
//
|
||||||
// Date : 20:51 2024/8/21
|
// Date : 20:51 2024/8/21
|
||||||
func (e *execute) Express(ctx context.Context, inputParam *define.Api2SqlParam) (any, error) {
|
func (e *execute) Express(ctx context.Context, inputParam *define.Api2SqlParam) (any, error) {
|
||||||
|
if nil == e.databaseClientManager {
|
||||||
|
return nil, errors.New("database client is nil, please use `SetDatabaseClientManager` set instance")
|
||||||
|
}
|
||||||
|
// 格式化 inputParam
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// formatAndValidateInputParam 格式化并校验输入参数
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 10:38 2024/8/22
|
||||||
|
func (e *execute) formatAndValidateInputParam(inputParam *define.Api2SqlParam) error {
|
||||||
|
if nil == inputParam {
|
||||||
|
return errors.New("inputParam is nil")
|
||||||
|
}
|
||||||
|
if len(inputParam.DatabaseFlag) == 0 {
|
||||||
|
return errors.New("databaseFlag is empty")
|
||||||
|
}
|
||||||
|
if len(inputParam.Table) == 0 {
|
||||||
|
return errors.New("table is empty")
|
||||||
|
}
|
||||||
|
if len(inputParam.SqlType) == 0 {
|
||||||
|
return errors.New("sqlType is empty")
|
||||||
|
}
|
||||||
|
databaseClient, err := e.databaseClientManager.GetDBClient(inputParam.DatabaseFlag)
|
||||||
|
if nil != err {
|
||||||
|
return errors.New(inputParam.DatabaseFlag + " : database client get fail -> " + err.Error())
|
||||||
|
}
|
||||||
|
// 尝试获取表结构, api 转 sql 要求必须开启表结构缓存, 否则无法确定相关数据如何解析
|
||||||
|
if inputParam.TableColumnConfig, err = databaseClient.GetTableFieldList(inputParam.Table); nil != err {
|
||||||
|
return errors.New(inputParam.DatabaseFlag + " : get table field list fail -> " + err.Error())
|
||||||
|
}
|
||||||
|
if len(inputParam.TableColumnConfig) == 0 {
|
||||||
|
return errors.New(inputParam.DatabaseFlag + " : table field list is empty, please enable `CacheDataTableStructureConfig` or `SetTableColumnConfig`")
|
||||||
|
}
|
||||||
|
// 操作字段列表为空
|
||||||
|
if len(inputParam.ColumnList) == 0 && wrapper.ArrayType[string]([]string{
|
||||||
|
consts.SqlTypeList, consts.SqlTypeDetail,
|
||||||
|
}).Has(inputParam.SqlType) >= 0 {
|
||||||
|
for _, itemParam := range inputParam.TableColumnConfig {
|
||||||
|
inputParam.ColumnList = append(inputParam.ColumnList, itemParam.ColumnName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 验证字段是否都正确
|
||||||
|
tableColumnTable := make(map[string]bool)
|
||||||
|
for _, itemColumn := range inputParam.TableColumnConfig {
|
||||||
|
tableColumnTable[itemColumn.ColumnName] = true
|
||||||
|
}
|
||||||
|
for _, item := range inputParam.ColumnList {
|
||||||
|
if !tableColumnTable[item] {
|
||||||
|
return errors.New(item + " : input column not found in table column list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, item := range inputParam.ValueList {
|
||||||
|
if !tableColumnTable[item.Column] {
|
||||||
|
return errors.New(item.Column + " : input column in `ValueList` is not found in table column list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 验证 force no limit
|
||||||
|
if inputParam.ForceNoLimit {
|
||||||
|
inputParam.Limit = 0
|
||||||
|
inputParam.WithCount = false
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -12,18 +12,35 @@ package define
|
|||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
//
|
//
|
||||||
// Date : 16:06 2024/8/21
|
// Date : 16:06 2024/8/21
|
||||||
|
//
|
||||||
|
// 一个合法的 sql 配置格式 :
|
||||||
|
//
|
||||||
|
// select 语句 : SELECT {FIELD_LIST} FROM {TABLE} WHERE {WHERE} ORDER BY {ORDER_FIELD} {ORDER_RULE} LIMIT {LIMIT} OFFSET {OFFSET}
|
||||||
|
//
|
||||||
|
// insert 语句 : INSERT INTO {TABLE} ({FIELD_LIST}) VALUES ({VALUE_LIST})
|
||||||
|
//
|
||||||
|
// update 语句 : UPDATE {TABLE} SET {SET} WHERE {WHERE} LIMIT {LIMIT} OFFSET {OFFSET} ORDER BY {ORDER_FIELD} {ORDER_RULE}
|
||||||
|
//
|
||||||
|
// delete 语句 : DELETE FROM {TABLE} WHERE {WHERE} LIMIT {LIMIT} OFFSET {OFFSET} ORDER BY {ORDER_FIELD} {ORDER_RULE}
|
||||||
|
//
|
||||||
|
// count 语句 : SELECT COUNT(*) FROM {TABLE} WHERE {WHERE}
|
||||||
type Api2SqlParam struct {
|
type Api2SqlParam struct {
|
||||||
DatabaseFlag string `json:"database_flag"` // 数据库标识
|
DatabaseFlag string `json:"database_flag"` // 数据库标识
|
||||||
InputSql string `json:"input_sql"` // 输入的sql模板, 仅依赖 ValueList 解析字段值, 依赖 split 相关解析分表配置
|
Table string `json:"table"` // 操作的数据表
|
||||||
TableSplit bool `json:"table_split"` // 是否分表
|
InputSql string `json:"input_sql"` // 输入的sql模板, 仅依赖 ValueList 解析字段值, 依赖 split 相关解析分表配置
|
||||||
SplitField string `json:"split_field"` // 分表字段, 仅分表时有效, 分表字段要求在 ValueList 必须存在
|
TableSplit bool `json:"table_split"` // 是否分表
|
||||||
SplitStrategy string `json:"split_strategy"` // 分表策略, 仅分表时有效, 支持注册自动以策略
|
SplitField string `json:"split_field"` // 分表字段, 仅分表时有效, 分表字段要求在 ValueList 必须存在
|
||||||
SqlType string `json:"sql_type"` // sql语句类型 : detail - 查询详情 list - 查询列表 count - 查询数量 update - 更新 insert - 插入 delete - 删除
|
SplitStrategy string `json:"split_strategy"` // 分表策略, 仅分表时有效, 支持注册自动以策略
|
||||||
FieldList []string `json:"field_list"` // 仅针对 select / detail 有效, 查询的字段列表
|
SqlType string `json:"sql_type"` // sql语句类型 : detail - 查询详情 list - 查询列表 count - 查询数量 update - 更新 insert - 插入 delete - 删除
|
||||||
OrderField string `json:"order_field"` // 排序字段, 仅 sqlType = list 生效
|
ColumnList []string `json:"column_list"` // 仅针对 select / detail 有效, 查询的字段列表
|
||||||
OrderRule string `json:"order_rule"` // 排序规则, Asc / Desc
|
Limit int64 `json:"limit"` // 操作数据量
|
||||||
WithCount bool `json:"with_count"` // 是否返回数据总量, 仅 sqlType = list 生效
|
Offset int64 `json:"offset"` // 操作偏移量
|
||||||
ValueList []*Api2SqlParamValue `json:"value_list"` // 字段列表
|
ForceNoLimit bool `json:"force_no_limit"` // 强制允许不限制 : 正常操作 select / delete / update 均需要指定本次操作数据量, 如果确定不限制, 此参数设置为 `true` , sqlType = list , 且 ForceNoLimit = true 时, WithCount 参数无效
|
||||||
|
OrderField string `json:"order_field"` // 排序字段, 仅 sqlType = list 生效
|
||||||
|
OrderRule string `json:"order_rule"` // 排序规则, Asc / Desc
|
||||||
|
WithCount bool `json:"with_count"` // 是否返回数据总量, 仅 sqlType = list 生效
|
||||||
|
ValueList []*Api2SqlParamValue `json:"value_list"` // 字段列表
|
||||||
|
TableColumnConfig []*ColumnInfo `json:"table_column_config"` // 表字段配置
|
||||||
}
|
}
|
||||||
|
|
||||||
// Api2SqlParamValue ...
|
// Api2SqlParamValue ...
|
||||||
@ -32,9 +49,9 @@ type Api2SqlParam struct {
|
|||||||
//
|
//
|
||||||
// Date : 16:11 2024/8/21
|
// Date : 16:11 2024/8/21
|
||||||
type Api2SqlParamValue struct {
|
type Api2SqlParamValue struct {
|
||||||
Field string `json:"field"` // 表字段
|
Column string `json:"column"` // 表字段
|
||||||
Value any `json:"value"` // 数据字段的值
|
Value any `json:"value"` // 数据字段的值
|
||||||
OutputName string `json:"output_name"` // 字段对外输出的名字, 不配置, 默认 与 Field 一致
|
Alias string `json:"alias"` // 字段对外输出的名字, 不配置, 默认 与 Field 一致, 仅查询语句生效
|
||||||
Default any `json:"-"` // 默认值 TODO : 配置默认值生成策略
|
Default any `json:"-"` // 默认值 TODO : 配置默认值生成策略
|
||||||
DataMask any `json:"-"` // 数据脱敏策略
|
DataMask any `json:"-"` // 数据脱敏策略
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user